面试题答案
一键面试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
上的thread1
。thread1
被唤醒后重新获取锁,继续执行后续代码。