JavaSE-多线程(12)- wait notify
程序中有一个容器,现需要实现如下内容:
线程1实现向容器添加10个元素,线程2实现元素个数监控,当添加到第5个元素时,线程2给出提示并结束
实现方式1
import java.util.ArrayList;
import java.util.List;
/**
* 线程1实现向容器添加10个元素,线程2实现元素个数监控,当添加到第5个元素时,线程2给出提示并结束
*/
public class VolatileTest3 {
//保证线程可见性,t1线程更改容器数据时,保证t2线程拿到最新容器容量
private volatile List<String> list = new ArrayList<String>();
public synchronized void add(String str) {
list.add(str);
}
public synchronized int size() {
return list.size();
}
public static void main(String[] args) {
VolatileTest3 volatileTest3 = new VolatileTest3();
Thread t1 = new Thread(() -> {
for (int i = 1; i <= 10; i++) {
System.out.println("add " + i + " start ");
/*try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
volatileTest3.add("str" + i);
System.out.println("add " + i + " end ");
}
});
t1.start();
Thread t2 = new Thread(() -> {
while (true) {
System.out.println("volatileTest3.size():" + volatileTest3.size());
if (volatileTest3.size() == 5) {
System.out.println("i=5 end");
break;
}
}
});
t2.start();
}
}
输出结果
add 1 start
add 1 end
add 2 start
add 2 end
add 3 start
add 3 end
add 4 start
add 4 end
add 5 start
add 5 end
volatileTest3.size():5
add 6 start
i=5 end
add 6 end
add 7 start
add 7 end
add 8 start
add 8 end
add 9 start
add 9 end
add 10 start
add 10 end
实现方式2
import java.util.ArrayList;
import java.util.List;
/**
* 线程1实现向容器添加10个元素,线程2实现元素个数监控,当添加到第5个元素时,线程2给出提示并结束
*/
public class WaitNotifyTest {
//保证线程可见性,t1线程更改容器数据时,保证t2线程拿到最新容器容量
private List<String> list = new ArrayList<String>();
public void add(String str) {
list.add(str);
}
public int size() {
return list.size();
}
public static void main(String[] args) {
VolatileTest3 volatileTest3 = new VolatileTest3();
Object lock = new Object();
Thread t2 = new Thread(() -> {
synchronized (lock) {
System.out.println("t2 线程开始");
if (volatileTest3.size() != 5) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("i=5 end");
//通知t1执行
lock.notify();
System.out.println("t2 线程结束");
}
});
t2.start();
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("t1 线程开始");
for (int i = 1; i <= 10; i++) {
System.out.println("add " + i + " start ");
volatileTest3.add("str" + i);
System.out.println("add " + i + " end ");
if (i == 5) {
//通知t2执行
lock.notify();
try {
/**
* 这一句不能少,因为notify不会立即释放锁,需要等synchronized方法体执行完才释放锁,
* 而wait会释放锁,所以t2线程才可以继续执行wait后的代码
*/
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("t1 线程结束");
}
});
t1.start();
}
}
运行结果:
t2 线程开始
t1 线程开始
add 1 start
add 1 end
add 2 start
add 2 end
add 3 start
add 3 end
add 4 start
add 4 end
add 5 start
add 5 end
i=5 end
t2 线程结束
add 6 start
add 6 end
add 7 start
add 7 end
add 8 start
add 8 end
add 9 start
add 9 end
add 10 start
add 10 end
t1 线程结束