Last active
March 22, 2018 06:02
-
-
Save zhanggang807/c060c8cc06b8146e8270b41503a81b7a to your computer and use it in GitHub Desktop.
java aqs official demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.io.ObjectInputStream; | |
import java.util.concurrent.TimeUnit; | |
import java.util.concurrent.locks.AbstractQueuedSynchronizer; | |
import java.util.concurrent.locks.Condition; | |
import java.util.concurrent.locks.Lock; | |
/** | |
* Here is a non-reentrant mutual exclusion lock class that uses the value zero to represent the unlocked state, | |
* and one to represent the locked state. While a non-reentrant lock does not strictly require recording of the | |
* current owner thread, this class does so anyway to make usage easier to monitor. It also supports conditions | |
* and exposes one of the instrumentation methods: | |
*/ | |
class Mutex implements Lock, java.io.Serializable { | |
// Our internal helper class | |
private static class Sync extends AbstractQueuedSynchronizer { | |
// Reports whether in locked state | |
protected boolean isHeldExclusively() { | |
return getState() == 1; | |
} | |
// Acquires the lock if state is zero | |
public boolean tryAcquire(int acquires) { | |
assert acquires == 1; // Otherwise unused | |
if (compareAndSetState(0, 1)) { | |
setExclusiveOwnerThread(Thread.currentThread()); | |
return true; | |
} | |
return false; | |
} | |
// Releases the lock by setting state to zero | |
protected boolean tryRelease(int releases) { | |
assert releases == 1; // Otherwise unused | |
if (getState() == 0) throw new IllegalMonitorStateException(); | |
setExclusiveOwnerThread(null); | |
setState(0); | |
return true; | |
} | |
// Provides a Condition | |
Condition newCondition() { | |
return new ConditionObject(); | |
} | |
// Deserializes properly | |
private void readObject(ObjectInputStream s) | |
throws IOException, ClassNotFoundException { | |
s.defaultReadObject(); | |
setState(0); // reset to unlocked state | |
} | |
} | |
// The sync object does all the hard work. We just forward to it. | |
private final Sync sync = new Sync(); | |
public void lock() { | |
sync.acquire(1); | |
} | |
public boolean tryLock() { | |
return sync.tryAcquire(1); | |
} | |
public void unlock() { | |
sync.release(1); | |
} | |
public Condition newCondition() { | |
return sync.newCondition(); | |
} | |
public boolean isLocked() { | |
return sync.isHeldExclusively(); | |
} | |
public boolean hasQueuedThreads() { | |
return sync.hasQueuedThreads(); | |
} | |
public void lockInterruptibly() throws InterruptedException { | |
sync.acquireInterruptibly(1); | |
} | |
public boolean tryLock(long timeout, TimeUnit unit) | |
throws InterruptedException { | |
return sync.tryAcquireNanos(1, unit.toNanos(timeout)); | |
} | |
} | |
//Here is a latch class that is like a CountDownLatch except that it only requires a single signal to fire. | |
// Because a latch is non-exclusive, it uses the shared acquire and release methods. | |
class BooleanLatch { | |
private static class Sync extends AbstractQueuedSynchronizer { | |
boolean isSignalled() { | |
return getState() != 0; | |
} | |
protected int tryAcquireShared(int ignore) { | |
return isSignalled() ? 1 : -1; | |
} | |
protected boolean tryReleaseShared(int ignore) { | |
setState(1); | |
return true; | |
} | |
} | |
private final Sync sync = new Sync(); | |
public boolean isSignalled() { | |
return sync.isSignalled(); | |
} | |
public void signal() { | |
sync.releaseShared(1); | |
} | |
public void await() throws InterruptedException { | |
sync.acquireSharedInterruptibly(1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment