有{1,2,3,4,5,6,7,8,9,10}和{10,20,30,40,50,60,70,80,90,100}两个数组,我们要实现的是分别打印1、2、10、20、3、4、30、40…
接下来我们将使用volatile和wait()、notify()两种方法来实现两个线程的交替打印。
一.使用volatile
public class UseVolatile {
static volatile boolean flag;
public static void main(String[] args) {
int[] arr1 = {1,2,3,4,5,6,7,8,9,10};
int[] arr2 = {10,20,30,40,50,60,70,80,90,100};
Thread t1 = new Thread(() -> {
int i = 0;
while (i < arr1.length){
if (!flag){
System.out.println(arr1[i++]);
System.out.println(arr1[i++]);
flag = true;
}
}
});
Thread t2 = new Thread(() -> {
int i = 0;
while (i < arr2.length){
if (flag){
System.out.println(arr2[i++]);
System.out.println(arr2[i++]);
flag = false;
}
}
});
t1.start();
t2.start();
}
}
正确运行结果如下图所示:
注意:如果不加volatile,则可能会出现两个线程都阻塞的情况。
因为可能t1执行flag=true后,并没有立马刷新到主内存,此时t1的工作内存中flag是true,则t1阻塞。与此同时t2从主内存读取的flag仍旧为false,所以t2也阻塞。
不加volatile的运行结果如下图所示:
二.使用wait()和notify()
public class UseWaitNotify {
int[] arr1 = {1,2,3,4,5,6,7,8,9,10};
int[] arr2 = {10,20,30,40,50,60,70,80,90,100};
public static void main(String[] args) {
UseWaitNotify useWaitNotify = new UseWaitNotify();
Thread t1 = new Thread(useWaitNotify::print1);
Thread t2 = new Thread(useWaitNotify::print2);
t1.start();
t2.start();
}
public synchronized void print1() {
int i = 0;
while (i < arr1.length){
System.out.println(arr1[i++]);
System.out.println(arr1[i++]);
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void print2() {
int i = 0;
while (i < arr2.length){
System.out.println(arr2[i++]);
System.out.println(arr2[i++]);
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果如下图所示: