Hi. I'm trying to implement a Java lock-type-thing which does the following:
- By default, threads do not pass the lock. (Opposite from normal locks, where locks can be acquired as long as they are not held.)
- If only one thread is waiting for the lock, execution in that thread stops
- If more than one thread is waiting for the lock, the thread that has been waiting the longest is allowed to continue execution.
I'm working on implementing this on top of AbstractQueuedSynchronizer. The transition to allow the oldest thread to go through looks like this:
//inner class inside Lock
private static class Sync extends AbstractQueuedSynchronizer {
public Sync(){
setState(-1);
}
public boolean tryAcquire(int ignore) {
if (getState() == 1) return false;
Thread first = getFirstQueuedThread();
if (first != null &&
first != Thread.currentThread()) {
setState(0);
return false;
}
return compareAndSetState(0, 1);
The problem that I'm seeing is that when I call setState(0) but return false, the Sync object never has the first thread tryAcquire again. Do I need to use SharedMode? Is there a better solution to this problem?
This is part of an implementation of what I call a "Valve" which I want to use for long-polling AJAX responses. I've got the part where a thread waits for the valve to become "pressurized" -- there's data to send to the client) but getting the oldest thread to release seems hard unless I don't use AbstractQueuedSynchronizer, and I really don't want to write a ground-up lock implementation.