基于白嫖黑马程序员白嫖视频:全面深入学习java并发编程,java基础进阶中级必会教程
1 场景
一个线程等待另一个线程的执行结果。
t1正常执行过程中,需要用到response值;t2负责给response赋值;
2 要点
- 传递仅仅是一个结果(一个数据类型、一个对象、一个文件等);
- 如果有多个,就需要消息队列(生产者/消费者);
- JDK中,join的实现、Future的实现,采用的是这个模式;
3 代码结构
3.1 GuardedObejet类
class GuardedObejet {
private Object object;//存放结果
//别人获取对象
public Object get() {
synchronized (this) {
//没有就等
while (object == null) {
try {
this.wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
//等到了返回
return this.object;
}
}
//别人产生对象
public void generate(Object object) {
synchronized (this) {
this.object = object;
this.notifyAll();
}
}
}
3.2 测试主类
public class Main {
public static void main(String[] args) {
GuardedObejet guardedObejet=new GuardedObejet();
//获取资源的线程
new Thread(()->{
System.out.println("等待获取资源");
Object object=guardedObejet.get();
System.out.println("获得成功");
}).start();
//产生资源的线程
new Thread(()->{
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//产生成功
guardedObejet.generate(new Object());
System.out.println("产生成功,通知大家");
}).start();
}
}
运行结果:
等待获取资源
产生成功,通知大家
获得成功
4 扩展1:添加超时等待
这部分时间的逻辑应该由get方法来控制,不应该直接交给wait,因为外层while始终没有获得到对象。 详见join(long )实现逻辑。
5 扩展2:多个产生多个接受
类似于邮递员给居民楼送邮件场景,这时候如果每个居民配备一个有邮递员成本就高了,为了实现解耦,需要添加一个额外的管理类(信箱)。
6 总结
- get方法中加while的意义在于,当唤醒我的时候,能不能保证对象已经给我了,这是对于自己代码鲁棒性的增强;