多个线程交替打印
wait和notify实现
注意点
1、wait方式是让当前持有锁的线程进入等待队列(不是阻塞队列),调用了wait方法后,当前线程就不会执行wait之后的代码逻辑了,所以notify方法必须在wait方法之前。
等待队列和阻塞队列的区别
对于每个对象来说,都有自己的等待队列和阻塞队列。
2、需要在循环结束后,加上notify,因为当其中一个线程正常执行完后,另一个线程一定还处于等待队列,所以最后需要被唤醒,如果不写,则虽然能正常打印出结果,但是程序不会结束。
3、要保证两个线程的开始顺序,因为thread.start方法,并不是先调用就一定是先调用的线程先执行,所以可以用countdownlatch来保证打印顺序的开始。
/**
* 线程交替打印
*/
public class Demo01 {
public static void main(String[] args) {
//两个线程分别来打印这两个数组
char[] arr1 = {'1', '2', '3', '4'};
char[] arr2 = {'a', 'b', 'c', 'd'};
//门闩,用于保证其中一个线程一定会先执行
CountDownLatch latch = new CountDownLatch(1);
//锁资源
Object lock = new Object();
new Thread(() -> {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
for (char c : arr1) {
System.out.println(c);
//必须要先使用notify
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//最后需要加上notify,防止另一个线程永远处于wait状态,程序不能正常介绍
lock.notify();
}
}).start();
new Thread(() -> {
synchronized (lock) {
for (char c : arr2) {
System.out.println(c);
if (latch.getCount() != 0L)
latch.countDown();
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notify();
}
}).start();
}
}