Java用不同的方法锁定和解锁.如何尝试/终于?

我试图弄清楚使用带锁的try / finally的最佳方法是什么.

当我在同一个地方有lock()和unlock()时,我只是使用try / finally块,因为JavaDoc也建议:

lock.lock();
try{
  // do something
} finally {
  lock.unlock();
}

我想知道当lock()和unlock()调用在单独的方法中时,使用try / finally的最佳做法是什么.

例如,请考虑以下事项:

public class X {
  private ReentrantLock lock = new ReentrantLock();

  public void pickUp(){
    lock.lock();
    // do something
  }

  public void putDown(){
    // do something
    lock.unlock();
  }
}

我要做的是将try / finally块放在上层,即每当我调用方法pickUp()和putDown()时.例如,在run()方法内部:

// class code
X x = new X();

public void run(){
  try{
    x.pickUp();
    // do something
  } finally {
    x.putDown();
  }
}

这是正确的方法吗?

非常感谢你.

解决方法:

这实际上是应用execute around method pattern的非常好的候选者.

如果您的类的客户端需要对需要正确初始化和/或正确清理的资源执行某些操作,您可以将清理保留在客户端的手中,并希望文档和失败的快速行为会使客户端正确处理资源.

通过初始化并从客户端再次清理出来,执行around方法模式带来了这个难题.基本上,您引入了一种方法,该方法可以正确地执行资源的初始化和清理,并且可以将其交给该资源的使用者.

理想情况下,您甚至可以完全封装执行初始化和清理的方法.

例如,根据您的示例代码:

private ReentrantLock lock = new ReentrantLock();

private void pickUp() { // now private
  lock.lock();
  // do something
}

private void putDown() { // now private
  // do something
  lock.unlock();
}

public void use(Consumer<X> consumer) {
  try {
    pickUp();
    consumer.accept(this);  // client gets its hands on the properly initialized resource.
  } finally {
    putDown();
  }
}

客户端仍然可以使用资源进行混乱的操作,例如在清理后在消费者之外使用它,但这已经很难了.记住正确的初始化和清理工作的困难部分不再是客户关注的问题.

上一篇:java – Hadoop datanode无法启动抛出org.apache.hadoop.hdfs.server.common.Storage:无法锁定存储


下一篇:Python并行执行-threading.Lock无法按预期工作