【问题标题】:Can i modify ReentrantLock so one can use it with try with resources?我可以修改 ReentrantLock 以便可以通过资源尝试使用它吗?
【发布时间】:2019-12-02 07:07:50
【问题描述】:

我想问一下这个实现是否可以,或者可能有一些问题可能会在以后出现问题。

这个想法是实现一个可与“资源尝试”一起使用的 ReentrantLock 类,这意味着它必须实现 AutoCloseable 接口。

另外,我想问一下为什么在“main”方法中编译器产生我必须添加一个“catch”子句,因为我的 close 方法(在 MyReentrantLock 中)不会抛出异常。

import java.util.concurrent.locks.ReentrantLock;

public class Ex09ReentrantLock {

    @SuppressWarnings("serial")
    public static class MyReentrantLock extends ReentrantLock implements AutoCloseable{

        public MyReentrantLock() {
            super();
            lock();
        }

        @Override
        public void close(){        
            unlock();
        }   
    }

    public static AutoCloseable lock() {

        var locker = new MyReentrantLock(); //lock() is called in the constructor

        return locker;  //implements AutoCloseable          
    }


    //Demo 
    public static void main(String[] args) {

        //try(ReentrantLock lock = new ReentrantLock()){} = compiler error

        try(var locker = lock();){          
            //some work...          
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }           
    }
}
  1. 这个实现好吗? (调用构造函数中的锁...)

  2. 如果我的 close 没有引发异常,为什么编译器会强制我添加 catch() 子句?

【问题讨论】:

  • 回答你的第二个问题:它迫使你捕捉Exception,因为你的#lock() 方法返回AutoCloseable,其#close() 方法确实声明自己抛出提到的例外。由于返回的声明类型是 AutoCloseable,编译器不知道 implementation 没有 throws 声明。您的方法必须返回 MyReentrantLock 以便编译器知道这些信息。

标签: java reentrantlock autocloseable


【解决方案1】:

锁是用来共享的。 锁定构造的锁只能使用new 锁定,因此不可共享意味着它无用。

我相信您的示例代码仅用于说明目的(但如果不是,这绝对是一个坏主意),以帮助您提供更多真实案例。

根据你分享的内容猜测,最接近你表达的是synchronized关键字。

一般来说,锁的交互很难处理,这就导致了同步机制的产生。应该在无法同步的非常特殊的情况下使用锁。

【讨论】:

  • 请注意,关于您的最后一段,在 Java 中 synchronized 机制实际上早于 Lock(在 Java 5 中添加)。如果我没记错的话,有一段时间,Lock API 在争用下实际上表现得更好,但我相信在较新的版本中不再如此(手头没有资源)。
  • 不确定我是否正确理解您的意思,但synchronized 使用监视器锁(本机实现),这与高级锁 API 不同。我曾经使用监视器构建了一个Lock,以便能够通过Lock API 使用synchronized 机制,使用一个有点隐藏的功能,可以手动进入或退出对象的内在锁。
  • 对我来说,您的最后一段暗示synchronized 是针对Lock 的一些失败/困难而创建的。现在,也许您一般参考的是编程历史,但在 Java 中,Locksynchronized 之后添加了许多版本。我很确定添加了Lock 以提供synchronized 无法提供的功能。我的第二句话是关于我记得读过的一些基准;首次添加时,Lock API 在竞争中的性能优于 synchronized — 但我相信它们在最近的 Java 版本中已经相互匹配。
  • 好的,谢谢,我知道在这种情况下,predates 是什么意思。
  • 当然,你是对的。低级 API 使用监视器锁来实现并发,例如 java.concurrent 包实现。锁更像是一个高级对象。同步关键字是对 Objet.wait/notify 等低级功能的高级“安全”访问。
猜你喜欢
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多