以前我们wait/notify notifyAll来实现线程的等待唤醒机制,可是notify 并不能精准地帮我唤醒我们想要唤醒的那个进程,这是可以使用ReenTrantLock+Condition来实现精准唤醒一个线程,每一个线程都会有一个Condition对象对唤醒。
直接上代码:
package com.richinfo.cn.reentrantlock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author : Allen(Wu Zhiwei)
* @date 创建时间:2018年5月18日 上午11:33:28
* @version 1.0
* @parameter
* @since
* @return
*/
public class MyService {
private ReentrantLock lock = new ReentrantLock();
private Condition ca = lock.newCondition();
private Condition cb = lock.newCondition();
public void awaitA(){
try{
lock.lock();
System.out.println(Thread.currentThread().getName() + ",start waitA");
ca.await();
System.out.println(Thread.currentThread().getName() + ",end waitA");
} catch (InterruptedException e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void awaitB(){
try{
lock.lock();
System.out.println(Thread.currentThread().getName() + ",start waitB");
cb.await();
System.out.println(Thread.currentThread().getName() + ",end waitB");
} catch (InterruptedException e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void singnalA(){
try{
lock.lock();
ca.signal();
System.out.println(Thread.currentThread().getName() + ",singnal A");
} finally {
lock.unlock();
}
}
}
测试类:
package com.richinfo.cn.reentrantlock;
/**
* @author : Allen(Wu Zhiwei)
* @date 创建时间:2018年5月18日 上午11:31:11
* @version 1.0
* @parameter
* @since
* @return
*/
public class Run {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
final MyService service = new MyService();
Runnable ra = new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
service.awaitA();
}
};
Runnable rb = new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
service.awaitB();
}
};
Thread threadA =new Thread(ra);
Thread threadB =new Thread(rb);
threadA.setName("A");
threadB.setName("B");
threadA.start();
threadB.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
service.singnalA();
}
}
控制台输出:
A,start waitA
B,start waitB
main,singnal A
A,end waitA