Thread 线程之间的通信方式
1.共享对象
Thread之间通过对象的属性来通信。
public class CallbackInstance {
private boolean hasRunCompute;
public synchronized boolean hasRunCompute() {
return hasRunCompute;
}
public synchronized void setHasRunCompute(boolean hasRunCompute) {
this.hasRunCompute = hasRunCompute;
}
}
线程通过共享CallbackInstance对象,查询CallbackInstance的flag状态来作为标识。
比如说执行一个大型运算操作,执行到某一步需要其他线程分别开始运算,当通知时other threads running。
public class ProcessCompute implements Runnable {
private CallbackInstance callbackInstance;
@Override
public void run() {
while(!callbackInstance.hasRunCompute()) {
//do something
}
}
}
通过将标识放在while循环中检查,这种方式会消耗CPU资源,会频繁的去获取锁然后检查标识状态,直到标识发生改变。
注意:需要共享对象的实例,即同一对象。
2.wait()、notify()、notifyAll()
public final void wait() throws InterruptedException;
public final native void wait(long timeout) throws InterruptedException;
public final native void notify();
public final native void notifyAll();
执行这几种方式都需要持有锁。线程进入Synchronized代码块或者Synchronized method,如果遇到wait() method,会释放持有的锁,进入对象的等待池等待唤醒或者到指定timeout时间切换为Runnalble(可运行)状态。当有线程执行notify()时,会唤醒在等待池中第一个执行wait()的线程,FIFO(First In - First Out)先进先出的概念。执行notifyAll()唤醒等待池中的all threads.
唤醒的thread会从等待池移除,变为可运行(Runnable)状态。
Application scenarios
现实中KFC的柜台人员和生产者,当柜台人员没有可售卖的商品时则会处于等待状态,此时相当于调用wait()方法,当厨房工作人员生产商品后则会通知柜台人员来取,根据售卖的先后顺序进行获取(notify)。
待续。