1.Condition实现等待和唤醒线程
java.util.locks.ReentrantLock用于替代synchronized加锁
但是synchronized可以使用wait和notify实现线程在条件不满足时的等待,条件满足时的唤醒。
如何使用ReentrantLock实现wait/notify的功能?
这个时候我们可以使用Condition对象来实现条件不满足时的等待,条件满足时的唤醒。
class TaskQueue{
final Lock lock = new ReentrantLock()
final Condition notEmpty = lock.newCondition();
}
1.1 对Condition对象调用await()方法就相当于对所对象调用wait()方法。
### 1.2 对Condition对象调用signalAll()就相当于在synchronized加锁对象调用notifyAll()方法。 Condition.await/signal/signalAll原理和wait/notify/notifyAll一致 * await()会释放当前锁,进入等待状态 * signal()会唤醒某个等待线程 * signalAll()会唤醒所有等待线程 * 唤醒线程从await()返回后需要重新获得锁2. 示例
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");
}
}
## 3. 总结
使用ReentrantLock+Condition可以更安全的实现线程的同步、等待和唤醒。
* Condition可以替代wait/notify
* Condition对象必须从ReentrantLock对象获取
* ReentrantLock+Condition可以替代synchronized+wait/notify