Using test-and-test-and-set.
See http://en.wikipedia.org/wiki/Spinlock, the section about optimizations. See also http://en.wikipedia.org/wiki/Test_and_Test-and-set.
This commit is contained in:
parent
d3786262af
commit
0636013d65
|
@ -20,9 +20,7 @@ package org.eclipse.jetty.util.thread;
|
|||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Spin Lock
|
||||
/**
|
||||
* <p>This is a lock designed to protect VERY short sections of
|
||||
* critical code. Threads attempting to take the lock will spin
|
||||
* forever until the lock is available, thus it is important that
|
||||
|
@ -43,12 +41,14 @@ public class SpinLock
|
|||
|
||||
public Lock lock()
|
||||
{
|
||||
Thread thread = Thread.currentThread();
|
||||
while(true)
|
||||
Thread current = Thread.currentThread();
|
||||
while (true)
|
||||
{
|
||||
if (!_lock.compareAndSet(null,thread))
|
||||
// Using test-and-test-and-set for better performance.
|
||||
Thread locker = _lock.get();
|
||||
if (locker != null || !_lock.compareAndSet(null, current))
|
||||
{
|
||||
if (_lock.get()==thread)
|
||||
if (locker == current)
|
||||
throw new IllegalStateException("SpinLock is not reentrant");
|
||||
continue;
|
||||
}
|
||||
|
@ -58,12 +58,7 @@ public class SpinLock
|
|||
|
||||
public boolean isLocked()
|
||||
{
|
||||
return _lock.get()!=null;
|
||||
}
|
||||
|
||||
public boolean isLockedThread()
|
||||
{
|
||||
return _lock.get()==Thread.currentThread();
|
||||
return _lock.get() != null;
|
||||
}
|
||||
|
||||
public class Lock implements AutoCloseable
|
||||
|
|
|
@ -18,17 +18,16 @@
|
|||
|
||||
package org.eclipse.jetty.util.thread;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class SpinLockTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void testLocked()
|
||||
{
|
||||
|
@ -70,7 +69,6 @@ public class SpinLockTest
|
|||
assertFalse(lock.isLocked());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testContend() throws Exception
|
||||
{
|
||||
|
@ -121,7 +119,7 @@ public class SpinLockTest
|
|||
};
|
||||
thread1.start();
|
||||
// thread1 will be spinning here
|
||||
assertFalse(held1.await(100,TimeUnit.MILLISECONDS));
|
||||
assertFalse(held1.await(100, TimeUnit.MILLISECONDS));
|
||||
|
||||
// Let thread0 complete
|
||||
hold0.countDown();
|
||||
|
@ -135,8 +133,5 @@ public class SpinLockTest
|
|||
thread1.join();
|
||||
|
||||
assertFalse(lock.isLocked());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue