【问题标题】:Is this a good implementation of a custom locking mechanism?这是自定义锁定机制的良好实现吗?
【发布时间】:2016-09-06 12:55:51
【问题描述】:

我有一个需要实现锁定机制的任务。这就是我到目前为止所拥有的。基本上我需要 lock 方法来尝试获取锁,如果获取锁则返回 true ,否则返回 false 。以及unlock方法尝试释放锁,成功则返回true,否则返回false。

这是实现此功能的正确方法,还是可以以其他方式完成?此代码可以添加哪些改进,或者可以通过哪些方式对其进行修改?

提前致谢,

安德烈

private Long threadId;

private int lockHolds;

public synchronized boolean lock(long waitTime) throws DataStoreException {
    if (lockHolds == 0) {
        doLock(waitTime);
        return true;
    }

    return false;
}

private synchronized void doLock(long waitTime) throws DataStoreException {
    if (lockHolds == 0) {
        lockHolds++;
        this.threadId = Thread.currentThread().getId();
    } else if (lockHolds > 0 && this.threadId == Thread.currentThread().getId()) {
        lockHolds++;
    } else {
        try {
            wait(waitTime);
            lockHolds++;
            this.threadId = Thread.currentThread().getId();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
    }

}

public synchronized boolean unlock() {
    if (lockHolds == 0) {
        return false;
    }

    lockHolds--;

    if (lockHolds == 0) {
        notify();
        return true;
    }

    return false;
}

【问题讨论】:

  • 使用synchronized 实现锁定有点弄巧成拙,不是吗?
  • CodeReview (codereview.stackexchange.com) 比 Stackoverflow 更适合工作代码的审查。
  • 为什么不使用 ReentrantLock 作为要测试的锁并删除同步关键字。

标签: java multithreading


【解决方案1】:
  1. 这是错误的:

    wait(waitTime);
    lockHolds++;
    this.threadId = Thread.currentThread().getId();
    

您只需等待,然后从当前拥有的线程中窃取锁。线程可能处于其临界区的中间,因此您允许并发访问临界区。

  1. wait 必须始终用于重复测试等待条件的循环中,以防止虚假唤醒。

  2. lock() 方法只检查lockHolds 变量,如果它非零则拒绝继续,从而防止锁的可重入行为。

  3. 您的unlock 方法是错误的,因为任何线程都可以调用它并释放另一个线程的锁。

虽然我不熟悉您的要求,但对我来说,请求自定义锁实现但允许它依赖内置锁实现和内置等待通知机制是很奇怪的。但这部分取决于你。

【讨论】:

    猜你喜欢
    • 2017-01-09
    • 2011-10-04
    • 1970-01-01
    • 2022-10-21
    • 1970-01-01
    • 2018-09-03
    • 2013-04-09
    • 2019-01-12
    • 1970-01-01
    相关资源
    最近更新 更多