前言
先来分析1波,object对象的wait和notify
Thread t1 = new Thread(()->{
synchronized (o){
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(111);
}
});
Thread t2 = new Thread(()->{
synchronized (o){
System.out.println(222222);
o.notify();
}
});
t1.start();
t2.start();
wait和notyfy方法必须配合synchronized使用,因为wait代表线程进入等待队列,等待获取锁,notify代表随机唤醒等待队列中的wait线程。
题目
启动两个线程, 一个输出 1,3,5,7…99, 另一个输出 2,4,6,8…100 最后 STDOUT 中按序输出 1,2,3,4,5…100。
要求用 Java 的 wait + notify 机制来实现
提示:wait和notify必须配合synchronized使用
代码
public class Juc_waitNotify {
public static Object lock=new Object();
public static List<Integer> list=new ArrayList<>();
public static void main(String[] args) {
Thread t1=new Thread(()->{
synchronized (lock){
try {
for (int i = 1; i <= 30; i++) {
if(i%2!=0){
System.out.print(Thread.currentThread().getName()+":"+i+",");
list.add(i);
lock.wait();
lock.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"线程A");
t1.start();
Thread t2=new Thread(()->{
synchronized (lock){
try {
for (int i = 1; i <= 30; i++) {
if (i % 2 == 0) {
System.out.print(Thread.currentThread().getName()+":"+i+",");
list.add(i);
lock.notify();
lock.wait();
}
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
},"线程B");
t2.start();
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("");
System.out.println("主线程");
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i)+" ");
}
}
}
运行结果:
引申题目
给定俩个数组{1,3,5,7,9},{2,4,6,8,10},利用多线程打印出
1,2,3,4,5,6,7,8,9,10
解法1引入CountDownLatch
public class PrintNum {
final static Object o=new Object();
public static void main(String[] args) {
CountDownLatch countDownLatch=new CountDownLatch(1);
List<Integer> listO=new ArrayList<>();
List<Integer> listJ=new ArrayList<>();
for (int i = 1; i <= 10; i++) {
if(i%2==0){
listO.add(i);
}
}
for (int i = 1; i <= 10; i++) {
if(i%2!=0){
listJ.add(i);
}
}
Thread t1 = new Thread(()->{
synchronized (o){
for (int i = 0; i < listJ.size(); i++) {
System.out.print(listJ.get(i)+" ");
countDownLatch.countDown();
try {
o.notify();
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();
}
});
Thread t2 = new Thread(()->{
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o){
for (int i = 0; i < listO.size(); i++) {
System.out.print(listO.get(i)+" ");
try {
o.notify();
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();
}
});
t1.start();
t2.start();
}
}
解法2利用voiatile
public class PrintNum {
final static Object o=new Object();
private static volatile boolean flag=false;
public static void main(String[] args) {
List<Integer> listO=new ArrayList<>();
List<Integer> listJ=new ArrayList<>();
for (int i = 1; i <= 100; i++) {
if(i%2==0){
listO.add(i);
}
}
for (int i = 1; i <= 100; i++) {
if(i%2!=0){
listJ.add(i);
}
}
Thread t1 = new Thread(()->{
synchronized (o){
for (int i = 0; i < listJ.size(); i++) {
System.out.print(listJ.get(i)+" ");
flag=true;
try {
o.notify();
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();
}
});
Thread t2 = new Thread(()->{
synchronized (o){
while (!flag){
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < listO.size(); i++) {
System.out.print(listO.get(i)+" ");
try {
o.notify();
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();
}
});
t1.start();
t2.start();
}
}