|
@@ -0,0 +1,81 @@
|
|
|
+package com.sf.javase.thread.commu;
|
|
|
+
|
|
|
+import lombok.SneakyThrows;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+// 模拟一个线程通信的场景
|
|
|
+// 首先要有两个线程 一个线程需要在另一个线程要求的某个条件下触发它
|
|
|
+// 一个线程在未满足条件时 要wait 另一个线程在满足了刚才的条件后 要notify
|
|
|
+public class TestNotify {
|
|
|
+
|
|
|
+ @SneakyThrows
|
|
|
+ public static void main(String[] args) {
|
|
|
+ // 创建一个list对象 代替Mylist
|
|
|
+ List<Integer> list = new ArrayList();
|
|
|
+ // 第一个线程需要等待
|
|
|
+ ThreadA threadA = new ThreadA(list);
|
|
|
+ threadA.start();
|
|
|
+ // 确保ThreadA先执行
|
|
|
+ Thread.sleep(100);
|
|
|
+
|
|
|
+ // 第二个线程需要触发唤醒
|
|
|
+ ThreadB threadB = new ThreadB(list);
|
|
|
+ threadB.start();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// MyList 提供一个多线程共享的容器
|
|
|
+
|
|
|
+class ThreadA extends Thread {
|
|
|
+ // 替换了原来的Object
|
|
|
+ private List list;
|
|
|
+
|
|
|
+ public ThreadA(List list) {
|
|
|
+ this.list = list;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ synchronized (list) {
|
|
|
+ if (list.size() < 3) {
|
|
|
+ try {
|
|
|
+ System.out.println("wait begin");
|
|
|
+ list.wait();
|
|
|
+ System.out.println("wait end");
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class ThreadB extends Thread {
|
|
|
+ private List list;
|
|
|
+
|
|
|
+ public ThreadB(List list) {
|
|
|
+ this.list = list;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Sneaky 暗中的 处理异常
|
|
|
+ @SneakyThrows
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ for (int i = 0; i < 6; i++) {
|
|
|
+ list.add(i);
|
|
|
+ System.out.println("add " + i);
|
|
|
+ // 尽量缩小锁的粒度
|
|
|
+ // 如果满足另一线程等待的条件 可以发起通知
|
|
|
+ synchronized (list) {
|
|
|
+ if (list.size() == 3) {
|
|
|
+ list.notify();
|
|
|
+ System.out.println("notify start");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Thread.sleep(1000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|