【问题标题】:Any risk in a AutoCloseable wrapper for java.util.concurrent.locks.Lock?java.util.concurrent.locks.Lock 的 AutoCloseable 包装器有什么风险吗?
【发布时间】:2013-05-10 13:46:48
【问题描述】:

在 Java 7 中引入了try-with-resource,我惊讶地发现Lock 没有被改造成AutoCloseable。看起来挺简单的,所以我自己加了如下:

class Lock implements AutoCloseable {
    private final java.util.concurrent.locks.Lock _lock;
    Lock(java.util.concurrent.locks.Lock lock) {
        _lock = lock;
        _lock.lock();
    }
    @Override 
    public void close() {
        _lock.unlock();
    }
}

这适用于AutoCloseableReentrantReadWiteLock 类,用法如下:

try (AutoCloseableReentrantReadWiteLock.Lock l = _lock.writeLock()) {
    // do something
}        

由于自动关闭RAII 的使用看起来如此简单和规范,我认为一定有充分的理由不应该这样做。有人知道吗?

【问题讨论】:

  • @rxg 我要恢复你的大部分编辑,我惊讶的不是它被引入的时候,而是最近我用它来锁
  • 没有问题,但你能修复 AutoCloseable 的链接吗?

标签: java raii try-with-resources auto-close


【解决方案1】:

try-with-resources 在 2009 年 2 月/3 月提出时引发了一场激烈的争论。

提案的作者乔什·布洛赫说“This construct was designed for one thing and one thing only: resource management. It was not designed for locking.

有一个单独的提议来单独覆盖锁,但它没有得到任何结果。

我认为锁没有被覆盖的主要原因是:

  • 无法在 Java 7 中向接口添加方法
  • 创建实现正确接口的额外包装对象的性能损失
  • 从哲学上反对 Lock 是一种不同于文件句柄的资源(例如,创建 Lock 并不需要调用 lock 方法)

您可以在the archive page 上关注所有历史上的讨价还价,例如this thread

【讨论】:

  • 感谢您提供的信息;对我来说,锁似乎是一种资源,但也许我缺少一些东西。在 Spring 世界中工作,包装器对性能的影响是无关紧要的。
  • @MiserableVariable:锁是一种资源,至少对我和 Dijkstra (:D) 而言,参见例如the Banker's algorithm description。不必每次都创建一个新对象(您只需要具有close 方法并且可以多次使用它的东西)。
  • @maaartinus 恐怕我不明白你在说什么。如果你有一个 close 方法,那么你还需要一个 open 方法,这就是 create 对 Lock 类所做的。
  • @Miserable 变量:您需要一个“打开”方法,但它可能看起来像AutoCloseable open() {lock(); return myCloseable;},其中myCloseable 是一个最终字段(并且“关闭”它显然会解锁锁)。跨度>
  • @MiserableVariable:对不起,我很困惑……你做得对。
猜你喜欢
  • 1970-01-01
  • 2010-11-24
  • 2012-05-26
  • 1970-01-01
  • 2011-11-07
  • 2021-11-03
  • 2018-09-11
  • 2014-01-30
  • 2018-11-06
相关资源
最近更新 更多