Java锁定结构最佳模式

Java锁定结构最佳模式,java,multithreading,Java,Multithreading,从技术角度来看,这两个列表有什么不同?第一个是java文档中提供的。第二个是我的 一, 二, 区别在于l为空时会发生什么: 第一个示例将失败,异常指向try块上方的第一行 第二个示例将失败,一个NPE被finally块抛出的另一个NPE屏蔽 此外,如果锁定失败,第二个示例中的finally块可能会尝试解锁未锁定的锁,而第一个示例不会解锁。原因如下: 实施考虑 锁实现通常会对哪个线程可以释放锁施加限制(通常只有锁的持有者可以释放锁),如果违反限制,则可能抛出(未选中的)异常。该锁实现必须记录任

从技术角度来看,这两个列表有什么不同?第一个是java文档中提供的。第二个是我的

一,

二,


区别在于
l
为空时会发生什么:

  • 第一个示例将失败,异常指向try块上方的第一行

  • 第二个示例将失败,一个NPE被finally块抛出的另一个NPE屏蔽


此外,如果锁定失败,第二个示例中的finally块可能会尝试解锁未锁定的锁,而第一个示例不会解锁。

原因如下:

实施考虑

锁实现通常会对哪个线程可以释放锁施加限制(通常只有锁的持有者可以释放锁),如果违反限制,则可能抛出(未选中的)异常。该锁实现必须记录任何限制和异常类型

类似地,
.lock()
可能会失败并出现未检查的异常

这意味着:

l.lock();
try {
    ...
} finally {
    l.unlock();
}
如果锁定失败,您将永远无法使用
unlock()
。鉴于:

try {
    l.lock();
    ...
} finally {
    lock.unlock();
}
如果锁定失败,则不必要地抛出两个异常;其中一个将会丢失


更不用说,根据锁的实现,在第二个版本中,您可能最终解锁“其他人”的锁。。。这不是一件好事。

这远远不是唯一可能的原因。。。如果
l
为空,那么您就有另一个问题要开始了!请参阅
lock()
上的JavaDoc,它允许实现在检测到错误使用时抛出未经检查的异常。一个例子可能是一个不可重入的锁,如果使用不当就会失败。@Ben:但它并没有说它锁定在关闭状态。而java.util.concurrent代码中的用法似乎并不关心这一点。因此,如果锁在锁操作中引发异常,它可能会处于锁定状态?@assylias这确实是另一个原因,是的;然而,据我所知,没有任何东西可以保证锁和解锁是由同一个线程完成的;如果有什么不同的话,它会使第一个版本的使用更加安全。好吧,也许我误读了文档——再次澄清,只有
lock
ing线程才能
unlock
。Assylias的注释将导致出现
非法监视器状态异常
l.lock();
try {
    ...
} finally {
    l.unlock();
}
try {
    l.lock();
    ...
} finally {
    lock.unlock();
}