首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AutoCloseable锁

AutoCloseable锁
EN

Code Review用户
提问于 2016-05-23 00:14:55
回答 1查看 971关注 0票数 2

令人惊讶的是,这个问题没有令人满意的答案。LockCloseable的安全使用将类似于

代码语言:javascript
运行
复制
try (LockCloseable lockCloseable = LockCloseable.lock(lock)) {
    doSomethingUnderLock();
} // automatic release

或者使用@lombok.Cleanup

代码语言:javascript
运行
复制
{
    @Cleanup LockCloseable lockCloseable = LockCloseable.lock(lock)
    doSomethingUnderLock();
} // automatic release when the scope is left

所有答案要么创建一个新的锁(无意义),要么当锁定时返回一个现有对象(危险)或返回空(无法用try-with资源)。

所以我试试看:

代码语言:javascript
运行
复制
@RequiredArgsConstructor(access=AccessLevel.PRIVATE)
public final class MgLockCloseable implements AutoCloseable {
    public static MgLockCloseable tryLock(Lock lock) {
        return new MgLockCloseable(lock.tryLock() ? lock : null);
    }

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

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

    public boolean isLocked() {
        return lock != null;
    }

    @Nullable private final Lock lock;
}

备注:

  • RequiredArgsConstructor来自lombok,完全按照名字的意思来做。
  • 我只实现了我需要的两种方法。
  • 它只是AutoCloseable,因为收尾不是幂等的。
EN

回答 1

Code Review用户

发布于 2017-03-20 12:28:14

如果在循环中获得的话,MgLockCloseable.tryLock()是不实用的。人们传统上是这样做的:

代码语言:javascript
运行
复制
while (!lock.tryLock()) {
    sleep();
}
try {
    // do locked stuff
} finally {
    lock.unlock();
}

这是使用MgLockClosable进行此操作所必需的:

代码语言:javascript
运行
复制
boolean processed = false;
while (!processed) {
    try (AutoClosable closable = MgLockClosable.tryLock()) {
        if (closable.isLocked()) {
            processed = true;
            // do locked stuff
        } else {
            sleep();
        }
    }
}

来自AutoClosable.close()的javadoc:

强烈鼓励该接口的实现者使其密切的方法成为幂等的。

很容易使close()实现幂等,并且在某些场景中很有用:

代码语言:javascript
运行
复制
try (MgLockClosable writeLocked = MgLockClosable.lock(getLock().writeLock()) {
    try (MgLockClosable ignored = MgLockClosable.lock(getLock().readLock()) {
        // do write lock related stuff
        writeLocked.close();
        // do write lock unrelated stuff (potentially slow)
    }
}

代码演示了读/写锁降级。将逻辑分成两个块,一个需要写锁,另一个需要读锁,具有更好的并发性。同时,代码仍然保存,因为在任何情况下都会释放这两个锁。

我会在lock()中交换这两行。如果构造函数抛出(由于任何原因,我们目前还不知道),那么锁将永远不会被解锁。另一方面,如果您交换行:如果构造函数抛出,则不会获得锁。如果Lock.lock()抛出,则永远不会返回MgLockCloseable实例。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/129068

复制
相关文章

相似问题

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