Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java以不同的方法锁定和解锁。如何尝试/最终?_Java_Multithreading_Concurrency_Locking - Fatal编程技术网

Java以不同的方法锁定和解锁。如何尝试/最终?

Java以不同的方法锁定和解锁。如何尝试/最终?,java,multithreading,concurrency,locking,Java,Multithreading,Concurrency,Locking,我正在试图找出使用try/finally锁的最佳方法 当我将lock()和unlock()放在同一个位置时,我只使用try/finally块,正如JavaDoc所建议的: lock.lock(); try{ // do something } finally { lock.unlock(); } 我想知道当lock()和unlock()调用在不同的方法中时,使用try/finally的最佳实践是什么 例如,考虑以下内容: public class X { private Reent

我正在试图找出使用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()
putton()
时。例如,在
run()
方法的内部:

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

public void run(){
  try{
    x.pickUp();
    // do something
  } finally {
    x.putDown();
  }
}
这是正确的方法吗


非常感谢。

这实际上是一个很好的申请者

如果类的客户机需要对需要正确初始化和/或正确清理的资源执行某些操作,则可以将清理工作交给客户机,并希望文档和fail fast行为能够促使客户机正确处理资源

方法模式的executearound解决了这个难题,它再次将初始化和清理从客户机手中夺走。基本上,您引入了一种方法,可以正确地初始化和清理资源,并将其交给该资源的
使用者

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

例如,根据示例代码:

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();
  }
}
private ReentrantLock lock=new ReentrantLock();
private void pickUp(){//现在是private
lock.lock();
//做点什么
}
private void放下(){//现在是private
//做点什么
lock.unlock();
}
公共无效使用(消费者){
试一试{
拾音器();
consumer.accept(this);//客户端获得正确初始化的资源。
}最后{
放下();
}
}

客户端仍然可以对资源进行混乱的操作,例如在清理之后在使用者之外使用资源,但这已经很难做到了。最难的部分,记住正确的初始化和清理,不再是客户机的问题。

这样做的危险在于,如果您的
//在
putton()中执行一些
可能引发异常,从而阻止调用
lock.unlock()
;因此,您需要编写
putton()
,这样才能调用
lock.unlock()
(例如,另一个
try/finally
块)。但是,如果
//do something
可能引发异常,我可以在同一
try/finally
块中添加
catch
子句,我不能吗?@MarkoTopolnik今晚我有更多的时间来扩展it@MarkoTopolnik希望您现在更喜欢:)