Java多執行緒學習筆記(五) 使用Condition實現等待/通知
阿新 • • 發佈:2018-11-08
使用Condition實現等待/通知
1. 使用Condition
在使用notify()/notifyAll()方法進行通知時,被通知的執行緒是由JVM隨機選擇的。但使用ReentrantLock類結合Condition類可以實現“選擇性通知”,這個功能是相當重要的。
1.1 MyService
public class MyService {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void await(){
try{
lock.lock();
System.out.println("await time is " + System.currentTimeMillis());
condition. await();
}catch (InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void signal(){
try{
lock.lock();
System.out.println("signal time is " + System.currentTimeMillis());
condition. signal();
}finally {
lock.unlock();
}
}
}
1.2 ThreadA
public class ThreadA extends Thread {
private MyService service;
public ThreadA(MyService service){
super();
this.service = service;
}
@Override
public void run(){
service.await();
}
}
1.3 Test
public class Test {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.start();
Thread.sleep(3000);
service.signal();
}
}
1.4 執行結果
await time is 1541569098094
signal time is 1541569101095
1.5 方法對比
Object類 | Condition類 |
---|---|
wait() | await() |
wait(long timeout) | await(long time, TimeUnit unit) |
notify() | signal() |
notifyAll() | signalAll() |
2. 使用多個Condition實現通知部分執行緒
2.1 MyService
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyService {
private Lock lock = new ReentrantLock();
public Condition conditionA = lock.newCondition();
public Condition conditionB = lock.newCondition();
//region await
public void awaitA(){
try{
lock.lock();
System.out.println("begin awaitA");
conditionA.await();
System.out.println("end awaitA");
}catch (InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void awaitB(){
try{
lock.lock();
System.out.println("begin awaitB");
conditionB.await();
System.out.println("end awaitB");
}catch (InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
//endregion
//region signalAll
public void signalAll_A(){
try{
lock.lock();
System.out.println("signalAll_A");
conditionA.signalAll();
}finally {
lock.unlock();
}
}
public void signalAll_B(){
try{
lock.lock();
System.out.println("signalAll_B");
conditionB.signalAll();
}finally {
lock.unlock();
}
}
//endregion
}
2.2 ThreadA
public class ThreadA extends Thread {
private MyService service;
public ThreadA(MyService service){
super();
this.service = service;
}
@Override
public void run(){
service.awaitA();
}
}
2.3 ThreadB
public class ThreadB extends Thread {
private MyService service;
public ThreadB(MyService service){
super();
this.service = service;
}
@Override
public void run(){
service.awaitB();
}
}
2.4 Test
public class Test {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
Thread.sleep(3000);
service.signalAll_A();
}
}
2.5 執行結果
begin awaitA
begin awaitB
signalAll_A
end awaitA