fre*_*low 42 java resources resource-management locks java-7
Locks AutoCloseable?也就是说,而不是:
Lock someLock = new ReentrantLock();
someLock.lock();
try
{
// ...
}
finally
{
someLock.unlock();
}
Run Code Online (Sandbox Code Playgroud)
我能说......么:
try (Lock someLock = new ReentrantLock())
{
someLock.lock();
// ...
}
Run Code Online (Sandbox Code Playgroud)
在Java 7中?
Ste*_*hen 53
我本人正在考虑自己这样做并做了类似这样的事情:
public class CloseableReentrantLock extends ReentrantLock implements AutoCloseable {
public CloseableReentrantLock open() {
this.lock();
return this;
}
@Override
public void close() {
this.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
然后这作为课程的用法:
public class MyClass {
private final CloseableReentrantLock lock = new CloseableReentrantLock();
public void myMethod() {
try(CloseableReentrantLock closeableLock = lock.open()) {
// locked stuff
}
}
}
Run Code Online (Sandbox Code Playgroud)
dle*_*lev 23
不,Lock
接口(也没有ReentrantLock
类)都没有实现AutoCloseable
接口,这是与新的try-with-resource语法一起使用所必需的.
如果你想让它工作,你可以编写一个简单的包装器:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以编写如下代码:
try (LockWrapper someLock = new LockWrapper(new ReentrantLock()))
{
someLock.lock();
// ...
}
Run Code Online (Sandbox Code Playgroud)
不过,我认为你最好坚持使用旧的语法.让锁定逻辑完全可见是更安全的.
通用ReentrantLock
既不实现也不提供任何实现AutoCloseable
try-with-resources语句所必需的接口的东西.但是,这个概念对Java API来说并不完全陌生,因为它FileChannel.lock()
提供了这个功能.
到目前为止给出的答案共享具有一些问题的解决方案,例如在每次锁定调用上创建不必要的对象,暴露容易出错的API或在获取锁定之后但在输入try-finally之前风险失败.
Java 7解决方案:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用lambda的Leaner Java 8解决方案:
public class CloseableReentrantLock extends ReentrantLock {
/**
* @return an {@link AutoCloseable} once the lock has been acquired.
*/
public ResourceLock lockAsResource() {
lock();
return this::unlock;
}
}
Run Code Online (Sandbox Code Playgroud)
示范:
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
}
Run Code Online (Sandbox Code Playgroud)
将try-with-resource
为其创建和销毁时的资源运作良好try-block
的离开了。它对于需要保持活动状态的资源不起作用。不会在每次使用时创建和销毁锁。它们保持活动状态,只是被锁定和解锁。这就是为什么它们不是这样AutoClosable
。
正如其他人已经建议的那样,可以使用包装器来创建和销毁包装,try-with-resource
并在创建和销毁时进行锁定和解锁。