java关于线程的三个包,廖雪峰Java11多线程编程-3高级concurrent包-3Condition

1.Condition实现等待和唤醒线程

java.util.locks.ReentrantLock用于替代synchronized加锁b35220fad830f0d71e820cc0d3fcca3e.png但是synchronized可以使用wait和notify实现线程在条件不满足时的等待,条件满足时的唤醒。如何使用ReentrantLock实现wait/notify的功能?这个时候我们可以使用Condition对象来实现条件不满足时的等待,条件满足时的唤醒。

class TaskQueue{

final Lock lock = new ReentrantLock()

final Condition notEmpty = lock.newCondition();

}

1.1 对Condition对象调用await()方法就相当于对所对象调用wait()方法。

bdd10514804f76abbec3f5ab9b05be36.png### 1.2 对Condition对象调用signalAll()就相当于在synchronized加锁对象调用notifyAll()方法。b459450ee9a25f135651d3846409d9cf.pngCondition.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 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");

}

}

00543d301135276e8c4dd1a10e792634.png## 3. 总结 使用ReentrantLock+Condition可以更安全的实现线程的同步、等待和唤醒。 * Condition可以替代wait/notify * Condition对象必须从ReentrantLock对象获取 * ReentrantLock+Condition可以替代synchronized+wait/notify