Condition实现等待和唤醒线程
java.util.locks.ReentrantLock用于替代synchronized加锁
synchronized可以使用wait和notify实现在条件不满足时的等待,条件满足时的唤醒。
class TaskQueue{
final Lock lock = new ReentrantLock()
final Condition notEmpty = lock.newCondition();
}
使用Condition对象可以通过await和signal实现条件不满足时的等待,条件满足时的唤醒
Condition.await/signal/signalAll原理和wait/notify/notifyAll一致
- await()会释放当前锁,进入等待状态
- signal()会唤醒某个等待线程
- signalAll()会唤醒所有等待线程
- 唤醒线程从await()返回后需要重新获得锁
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class TaskQueue{
final Queue<String> queue = new LinkedList<>();
final Lock lock = new ReentrantLock();
final Condition notEmpty = lock.newCondition();
public String getTask() throws InterruptedException{
lock.lock();
try{
while(this.queue.isEmpty()){
notEmpty.await();
}
return queue.remove();
}finally {
lock.unlock();
}
}
public void addTask(String name){
lock.lock();
try{
this.queue.add(name);
notEmpty.signalAll();
}finally {
lock.unlock();
}
}
}
class WorkerThread extends Thread{
TaskQueue taskQueue;
public WorkerThread(TaskQueue taskQueue){
this.taskQueue = taskQueue;
}
public void run(){
while(!isInterrupted()){
String name;
try{
name = taskQueue.getTask();
}catch (InterruptedException e){
break;
}
String result = "Hello, "+name+" !";
System.out.println(result);
}
}
}
public class Main{
public static void main(String[] args) throws InterruptedException{
TaskQueue taskQueue = new TaskQueue();
WorkerThread worker = new WorkerThread(taskQueue);
worker.start();
taskQueue.addTask("Bob");
Thread.sleep(1000);
taskQueue.addTask("Alice");
Thread.sleep(1000);
taskQueue.addTask("Tim");
Thread.sleep(1000);
worker.interrupt();
worker.join();
System.out.println("END");
}
}
总结
- Condition可以替代wait/notify
- Condition对象必须从ReentrantLock对象获取
- ReentrantLock+Condition可以替代synchronized+wait/notify