java - ReentrantLock and Condition,最佳设计

标签 java multithreading thread-safety locking

我正在资源池的上下文中使用 ReentrantLock 中的条件,据我所知,它简化了线程通信。我的问题是,我最终有机地编写了奇怪的条件,例如 acquireMapEmpty、freeQueueNotEmpty、更改等待和单个不同的东西。从技术上讲,它们可以全部替换为一个条件或分解为多个条件 - 是否有以下经验法则:

  1. 确定条件
  2. 弄清楚您的数量是否过多或过少
  3. 当您走在正确的轨道上或偏离轨道时

以下是删除资源的示例。

 public boolean remove(R resource) throws InterruptedException {

    System.out.println("Remove, resource: " + resource + " with thread: " + Thread.currentThread().getName());
    if (resource == null) {
        throw new NullPointerException();
    }
    mainLock.lock();
    try {
        if (!isOpen) {
            throw new IllegalStateException("Not open");
        }
        Object lock = locks.get(resource);
        if (lock == null) {
            return false;
        }
        if (freeQueue.remove(resource)) {
            locks.remove(resource);
            if (!freeQueue.isEmpty()) {
                freeQueueNotEmpty.signalAll();
            }
            return true;
        }
        while (!freeQueue.contains(resource)) {
            change.await();
            if (!isOpen) {
                throw new IllegalStateException("Not open");
            }
            lock = locks.get(resource);
            if (lock == null) {
                return false;
            }
        }
        if (freeQueue.remove(resource)) {
            locks.remove(resource);
            if (!freeQueue.isEmpty()) {
                freeQueueNotEmpty.signalAll();
            }
            return true;
        }
        return false;
    } finally {
        mainLock.unlock();
    }
}

最佳答案

嗯,根据经验,我倾向于拥有与线程阻塞的原因一样多的条件变量。基本原理是,当您发出条件变量信号时,您想要唤醒一个正在等待您发出信号的状态的特定变化的线程,并且您真的非常想避免“惊群”综合症 - 唤醒 所有线程,在某个条件下被阻塞,只是让其中一个取得进展,而所有其他线程又回到 sleep 状态,同时浪费了宝贵的CPU时间并破坏了缓存。

关于java - ReentrantLock and Condition,最佳设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13465245/

相关文章:

用户名的 Java 正则表达式

thread-safety - Kotlin 单例线程安全吗?

java - Android 示例无法编译

java - 使用 Facebook 登录/注册 - 测试用户

java - 在java中检查有效的括号

c++ - 为什么在单独的线程中调用成员成员函数会导致不确定的行为?

java - 什么定义了对象的状态?

python-3.x - 服务器仅打印来自最近连接的客户端的消息

java - 为什么 newInstance 在我的代码中抛出 InstantiationException?

c# - 使用 C# 的线程池问题