Created
December 6, 2016 16:27
-
-
Save kostapc/c8009779b61cd3918a03efc5b1f81fe6 to your computer and use it in GitHub Desktop.
Single Latch - thread wait for "open" or pass through await() instantly if latch open
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
public class SingleLatch { | |
static final int STATE_OPEN = 0; | |
static final int STATE_CLOSED = 1; | |
public enum State { | |
OPEN(STATE_OPEN), | |
CLOSED(STATE_CLOSED); | |
int state; | |
State(int state) { | |
this.state = state; | |
} | |
int getInt() { | |
return state; | |
} | |
static State valueOf(int state) { | |
switch (state) { | |
case STATE_OPEN: return OPEN; | |
case STATE_CLOSED: return CLOSED; | |
default: | |
throw new IllegalStateException("state "+state+" not declared"); | |
} | |
} | |
} | |
/** | |
* Synchronization control For SingleLatch. | |
* Uses AQS state to represent count. | |
*/ | |
private static final class Sync extends AbstractQueuedSynchronizer { | |
private static final long serialVersionUID = 4982267854940614374L; | |
Sync() { | |
setState(State.CLOSED.getInt()); | |
} | |
State getSyncState() { | |
return State.valueOf(getState()); | |
} | |
@Override | |
protected int tryAcquireShared(int acquires) { | |
return (getState() == STATE_OPEN) ? 1 : -1; | |
} | |
@Override | |
protected boolean tryReleaseShared(int releases) { | |
setState(STATE_OPEN); | |
return true; | |
} | |
} | |
private final SingleLatch.Sync sync; | |
public SingleLatch() { | |
this.sync = new SingleLatch.Sync(); | |
} | |
public void await() throws InterruptedException { | |
sync.acquireSharedInterruptibly(State.OPEN.getInt()); | |
} | |
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { | |
return sync.tryAcquireSharedNanos(State.OPEN.getInt(), unit.toNanos(timeout)); | |
} | |
public void open() { | |
sync.releaseShared(State.OPEN.getInt()); | |
} | |
public boolean isClosed() { | |
return State.CLOSED.equals(sync.getSyncState()); | |
} | |
public String toString() { | |
return super.toString() + "[Count = " + sync.getSyncState() + "]"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment