等待/通知机制
2017-11-02 本文已影响36人
hxg_
原文地址:https://hexige.github.io/blog/2017/09/25/%E7%AD%89%E5%BE%85%E9%80%9A%E7%9F%A5%E6%9C%BA%E5%88%B6/
等待/通知机制
一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作。前者为生产者,后者为消费者。
消费者:
- 获取对象的锁;
- 如果条件不满足,调用对象的wait方法;
- 条件满足则进行对应的操作;
sync(obj){
whlie(条件不满足){
obj.wait();
}
对应的操作;
}
生产者:
- 获取对象的锁;
- 改变条件;
- 通知所有等待在该对象上的线程;
sync(obj){
改变条件;
obj.notifyAll();
}
Thread.join()
Waits for this thread to die.
如果一个线程A执行了threadB.join(),则表示线程A在threadB终止前一hang住,直到threadB终止,线程A才继续执行后续的操作;
public static void main(String[] args) {
Thread cur = Thread.currentThread();
for(int i =0;i<3;i++){
Thread thread = new Thread(new MRunaable(cur),String.valueOf(i));
thread.start();
cur = thread;
}
}
static class MRunaable implements Runnable{
private Thread preThread;
public MRunaable(Thread preThread) {
this.preThread = preThread;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
preThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
此时会按顺序输出线程名,即:等待前一个线程执行完后,才执行下面的输出语句。若不使用preThread.join()方法,输出的线程名不一定按照顺序输出。
join方法源码:
public final void join(long millis) throws InterruptedException {
synchronized(lock) {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
lock.wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
lock.wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
}
join方法中的逻辑同等待/通知机制一致.
//条件不满足,等待
while (isAlive()) {
lock.wait(0);
}
//满足,方法返回