Alternative to Lock.tryLock() in Java 1.4

2019-07-20 18:59发布

问题:

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…)