ReentrantLock的多个条件用法

Conditionjava.util.concurrent.locks 包中的一个接口,它提供了类似于传统的线程间通信机制(如 wait()notify()notifyAll())的功能,但更强大和灵活。通过 lock.newCondition() 可以创建多个条件变量。

以下是一个简单的示例,展示了如何使用 ReentrantLockCondition 来支持多个条件变量:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class MultiConditionExample {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition condition1 = lock.newCondition();  // 条件变量1
    private final Condition condition2 = lock.newCondition();  // 条件变量2

    private int count = 0;

    // 线程1
    public void waitForCondition1() throws InterruptedException {
        lock.lock();
        try {
            while (count != 1) {
                condition1.await();  // 等待条件1满足
            }
            System.out.println("Condition 1 met, processing in thread 1...");
            count = 2; // 更新条件状态
            condition2.signal();  // 唤醒等待条件2的线程
        } finally {
            lock.unlock();
        }
    }

    // 线程2
    public void waitForCondition2() throws InterruptedException {
        lock.lock();
        try {
            while (count != 2) {
                condition2.await();  // 等待条件2满足
            }
            System.out.println("Condition 2 met, processing in thread 2...");
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MultiConditionExample example = new MultiConditionExample();

        // 启动两个线程
        Thread t1 = new Thread(() -> {
            try {
                example.waitForCondition1();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                example.waitForCondition2();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        t1.start();
        t2.start();

        // 主线程控制条件的变化
        Thread.sleep(1000); // 给线程1和线程2一点时间启动
        example.lock.lock();
        try {
            example.count = 1;  // 设置条件1满足
            example.condition1.signal();  // 唤醒等待条件1的线程
        } finally {
            example.lock.unlock();
        }

        t1.join();
        t2.join();
    }
}

代码说明:

  1. ReentrantLock:我们使用 ReentrantLock 来确保多个线程之间对共享资源(如 count)的互斥访问。
  2. Condition:我们使用了两个不同的条件变量 condition1condition2,分别用于控制不同的线程逻辑。
  3. await():线程在某个条件变量上等待,直到条件满足。
  4. signal():唤醒等待指定条件变量的一个线程。
  5. while (count != 1)这里,如果条件满足,线程会调用 await(),线程1会在 await() 处被阻塞,线程1会一直停留在 await() 处,不会向下执行。

执行顺序:

  • 线程1在等待 count 为1时进入 await() 阻塞。
  • 线程2在等待 count 为2时进入 await() 阻塞。
  • 主线程修改 count 为1并唤醒线程1,线程1处理完毕后修改 count 为2,并唤醒线程2。
  • 最后,线程2被唤醒并处理。

这样就实现了多个条件变量的使用,每个条件变量控制不同线程的执行顺序。

你可能感兴趣的:(面试,java,算法,开发语言)