为什么不在java中使用带有锁的try?

2024-01-01

我读了这个话题 https://stackoverflow.com/questions/6965731/are-locks-autocloseable, 和这个博客文章 http://www.java7developer.com/blog/?p=256 about 尝试使用资源锁,当这个问题出现在我脑海中时。 但实际上,我更想要的是尝试用锁,我的意思是没有锁实例化。它将把我们从冗长的

lock.lock();
try {
    //Do some synchronized actions throwing Exception 
} finally {
    //unlock even if Exception is thrown
    lock.unlock();
}

宁愿看起来像:

? implements Unlockable lock ;
...
try(lock) //implicitly calls lock.lock() 
{
    //Do some synchronized actions throwing Exception 
} //implicitly calls finally{lock.unlock();}

So 它不会是行波堆,但只是一些样板清理。

您是否有任何技术原因建议描述why这不是一个合理的想法吗?

编辑:澄清我的建议和简单的之间的区别synchronized(lock){}块,检查这个片段:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;


public class Test {

        public static void main(String[] args) {
                ReentrantLock locker =new ReentrantLock();
                Condition condition = locker.newCondition();
                Thread t1 = new Thread("Thread1") {
                        @Override
                        public void run(){
                                synchronized(locker){
                                        try {
                                                condition.await();
                                        } catch (InterruptedException e) {
                                                Thread.currentThread().interrupt();
                                        }
                                        System.out.println("Thread1 finished");
                                }
                        }
                } ;
                Thread t2 = new Thread("Thread2") {
                        @Override
                        public void run(){
                                synchronized(locker){
                                        Thread.yield();
                                        condition.signal();
                                        System.out.println("blabla2");
                                }
                        }
                } ;
                t1.start();
                t2.start();
        }

}

执行将导致IllegalMonitorStateException,因此 lock() 和unlock() 方法不会在内部隐式调用synchronized block.


如果您必须处理这样的简单情况,其中锁定/解锁的模式仅限于这样的狭窄范围,您可能不想使用更复杂的Lock http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html类,可能应该使用synchronized关键字,而不是。话虽这么说,如果出于某种原因您需要使用更复杂的 Lock 对象,那么创建一个实现 Lock 的包装器应该相对简单自动关闭 http://docs.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html接口能够做到这一点。例子:

class AutoUnlock implements AutoCloseable {
  private final Lock lock;

  public static AutoUnlock lock(Lock lock) {
    lock.lock();
    return new AutoUnlock(lock);
  }

  public static AutoUnlock tryLock(Lock lock) {
    if (!lock.tryLock()) {
       throw new LockNotAcquiredException();
    }
    return new AutoUnlock(lock);
  }

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

  private AutoUnlock(Lock lock) {
    this.lock = lock;
  }
}

使用上面的包装器,您可以执行以下操作:

try (AutoUnlock autoUnlock = AutoUnlock.lock(lock)) {
  // ... do whatever that requires the lock ...
}

话虽这么说,Lock 类通常用于非常复杂的锁定场景,在这种情况下这并不是特别有用。例如,Lock 对象可以在类中的一个函数中锁定,然后在另一个函数中解锁(例如,响应传入的远程过程调用锁定数据库中的一行,然后响应稍后的 RPC 解锁该行),因此,拥有这样的包装器或将 Lock AutoCloseable 本身设置为实际使用方式的用途有限。对于更简单的场景,更常见的是仅使用现有的并发数据结构或使用同步。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么不在java中使用带有锁的try? 的相关文章

随机推荐