首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锁是AutoCloseable吗?

锁是AutoCloseable吗?
EN

Stack Overflow用户
提问于 2011-08-06 16:46:36
回答 12查看 15.6K关注 0票数 46

Locks是自动关闭的吗?也就是说,而不是:

代码语言:javascript
复制
Lock someLock = new ReentrantLock();
someLock.lock();
try
{
    // ...
}
finally
{
    someLock.unlock();
}

...can我说:

代码语言:javascript
复制
try (Lock someLock = new ReentrantLock())
{
    someLock.lock();
    // ...
}

...in Java7?

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2011-08-06 16:49:56

不需要,Lock接口(和ReentrantLock类)都不实现AutoCloseable接口,该接口是使用新的try- with -resource语法所必需的。

如果你想让它工作,你可以写一个简单的包装器:

代码语言:javascript
复制
public class LockWrapper implements AutoCloseable
{
    private final Lock _lock;
    public LockWrapper(Lock l) {
       this._lock = l;
    }

    public void lock() {
        this._lock.lock();
    }

    public void close() {
        this._lock.unlock();
    }
}

现在,您可以像这样编写代码:

代码语言:javascript
复制
try (LockWrapper someLock = new LockWrapper(new ReentrantLock()))
{
    someLock.lock();
    // ...
}

不过,我认为您最好还是坚持使用旧的语法。让你的锁定逻辑完全可见会更安全。

票数 25
EN

Stack Overflow用户

发布于 2012-06-13 00:04:29

我正在考虑自己做这件事,并做了这样的事情:

代码语言:javascript
复制
public class CloseableReentrantLock extends ReentrantLock implements AutoCloseable { 
   public CloseableReentrantLock open() { 
      this.lock();
      return this;
   }

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

然后是这个类的用法:

代码语言:javascript
复制
public class MyClass {
   private final CloseableReentrantLock lock = new CloseableReentrantLock();

   public void myMethod() {
      try(CloseableReentrantLock closeableLock = lock.open()) {
         // locked stuff
      }
   }
}
票数 60
EN

Stack Overflow用户

发布于 2017-09-16 08:22:05

通用ReentrantLock既不实现也不提供实现try-with-resources语句所需的AutoCloseable接口的任何内容。但是,这个概念对于Java API来说并不完全陌生,因为FileChannel.lock()提供了这个功能。

到目前为止,给出的答案都是有一些问题的解决方案,比如在每次锁调用时创建一个不必要的对象,暴露一个容易出错的API,或者在获取锁之后但进入try-finally之前有失败的风险。

Java 7解决方案:

代码语言:javascript
复制
public interface ResourceLock extends AutoCloseable {

    /**
     * Unlocking doesn't throw any checked exception.
     */
    @Override
    void close();
}

public class CloseableReentrantLock extends ReentrantLock {

    private final ResourceLock unlocker = new ResourceLock() {
        @Override
        public void close() {
            CloseableReentrantLock.this.unlock();
        }
    };

    /**
     * @return an {@link AutoCloseable} once the lock has been acquired.
     */
    public ResourceLock lockAsResource() {
        lock();
        return unlocker;
    }
}

使用lambda的更精简的Java8解决方案:

代码语言:javascript
复制
public class CloseableReentrantLock extends ReentrantLock {

    /**
     * @return an {@link AutoCloseable} once the lock has been acquired.
     */
    public ResourceLock lockAsResource() {
        lock();
        return this::unlock;
    }
}

演示:

代码语言:javascript
复制
public static void main(String[] args) {
    CloseableReentrantLock lock = new CloseableReentrantLock();

    try (ResourceLock ignored = lock.lockAsResource()) {
        try (ResourceLock ignored2 = lock.lockAsResource()) {
            System.out.println(lock.getHoldCount());  // 2
        }
    }
    System.out.println(lock.getHoldCount());  // 0
}
票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6965731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档