我读了这个话题 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(使用前将#替换为@)