MST
星途 面试题库

面试题:Java中条件变量的基本应用场景

请简述在Java中,条件变量(Condition)通常会在哪些场景下使用,并给出一个简单的多线程协作示例,说明如何利用条件变量实现线程间的精准通知与等待。
36.5万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. 条件变量(Condition)的使用场景

  • 多线程协作场景:当多个线程需要在特定条件满足时进行协作,例如生产者 - 消费者模式。生产者线程在缓冲区未满时生产数据,消费者线程在缓冲区有数据时消费数据。Condition 可以实现线程间的精准通知与等待,避免不必要的轮询。
  • 复杂同步场景:当同步机制不仅仅依赖于简单的锁(如 synchronized),还需要更细粒度的控制时,Condition 可以结合 Lock 使用。例如,一个线程需要等待另一个线程完成一系列操作后才能继续执行,Condition 可以提供这种精准的等待和唤醒机制。

2. 多线程协作示例

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

public class ConditionExample {
    private static final Lock lock = new ReentrantLock();
    private static final Condition condition = lock.newCondition();
    private static boolean flag = false;

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            lock.lock();
            try {
                while (!flag) {
                    System.out.println("Thread1 is waiting...");
                    condition.await();
                }
                System.out.println("Thread1 is notified and continues execution.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });

        Thread thread2 = new Thread(() -> {
            lock.lock();
            try {
                System.out.println("Thread2 is changing the condition.");
                flag = true;
                condition.signal();
                System.out.println("Thread2 has signaled Thread1.");
            } finally {
                lock.unlock();
            }
        });

        thread1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread2.start();
    }
}

在上述示例中:

  • 首先创建了一个 ReentrantLock 和与之关联的 Condition
  • thread1 获取锁后,检查 flag 条件,如果不满足则调用 condition.await() 进入等待状态,同时释放锁。
  • thread2 获取锁后,改变 flag 的值为 true,并调用 condition.signal() 唤醒等待在 condition 上的 thread1thread1 被唤醒后重新获取锁,继续执行后续代码。