/**
* This is description.
* 面试题(画示意图): 实现一个容器, 有两个要求:
* 1. add, size.
* 2. 写2个线程, 线程1添加10个元素到容器中, 线程2实现监控元素个数, 当个数到达5个时, 线程2给出提示并结束(线程2结束).
* Container4利用双重wait和notify优化Container3的"当前线程名: t2结束."语句只能等待t1线程执行结束后才会被打印.
*
* @author Chris Lee
* @date 2019/3/16 10:18
*/
public class Container4 {
volatile List<Object> list = new ArrayList<>(10);
public void add(Object object) {
list.add(object);
}
public int size() {
return list.size();
}
public static void main(String[] args) {
Container2 container1 = new Container2();
Object lock = new Object();
new Thread(() -> {
synchronized (lock) {
for (int i = 0; i < 10; i++) {
container1.add(new Object());
System.out.println("当前线程名: " + Thread.currentThread().getName() + ", i = " + i);
if (container1.size() == 5) {
// 唤醒t2线程继续执行.
lock.notify();
try {
// t1线程进入等待状态.
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "t1").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
synchronized (lock) {
System.out.println("当前线程名: " + Thread.currentThread().getName() + "启动.");
if (container1.size() != 5) {
try {
// t2线程进入等待状态.
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("当前线程名: " + Thread.currentThread().getName() + "结束.");
// 唤醒t1线程继续执行.
lock.notify();
}
}, "t2").start();
/*
当前线程名: t1, i = 0
当前线程名: t1, i = 1
当前线程名: t1, i = 2
当前线程名: t1, i = 3
当前线程名: t1, i = 4
当前线程名: t2启动.
当前线程名: t2结束.
当前线程名: t1, i = 5
当前线程名: t1, i = 6
当前线程名: t1, i = 7
当前线程名: t1, i = 8
当前线程名: t1, i = 9
*/
}
}
说明:
- 本篇文章如有不正确或待改进的地方, 欢迎批评和指正, 大家一同进步, 谢谢!
- 世上有4样东西可以让世界变得更美好, 它们是: 代码(Code), 诗(Poem), 音乐(Music), 爱(Love). 如有兴趣了解更多, 欢迎光顾"我的文集"相关文章.
资料:
- 学习视频: https://www.bilibili.com/video/av11076511/?p=1
- 参考代码: https://github.com/EduMoral/edu/tree/master/concurrent/src/yxxy
- 我的代码: https://github.com/ChrisLeejing/learn_concurrency.git