I would like to know if there is an existing alternative or how to implement the semantics of java.util.concurrent.locks.Lock#tryLock() before Java 5. That is the possibility to back off immediately if the lock is already held by another thread.
问题:
回答1:
If you need a Lock
supporting a tryLock
operation, you can’t use the intrinsic locking facility of Java. You have to implement your own Lock
class which maintains the required state, i.e. an owner Thread
and a counter and might use the intrinsic locking for its implementation of the thread-safe updates and blocking (there are not much alternatives in older Java versions).
A very simple implementation might look like this:
public final class Lock {
private Thread owner;
private int nestCount;
public synchronized void lock() throws InterruptedException {
for(;;) {
if(tryLock()) return;
wait();
}
}
public synchronized boolean tryLock() {
Thread me=Thread.currentThread();
if(owner!=me) {
if(nestCount!=0) return false;
owner=me;
}
nestCount++;
return true;
}
public synchronized void unlock() {
if(owner!=Thread.currentThread())
throw new IllegalMonitorStateException();
if(--nestCount == 0) {
owner=null;
notify();
}
}
}
Note that the intrinsic lock of the Lock
instance enforced by the synchronized
methods is hold for a very short time only. The threads will either return immediately or go into the wait
state which implies releasing the lock as well. Hence the tryLock
will exhibit the desired behavior, though the Java 5 and newer equivalent will likely be more efficient. (The Java 5 and newer implementation of synchronized
is more efficient as well…)