问题
开启两个线程,分别交替打印奇数、偶数。
打印信息大致如下:
线程1:奇数
线程2:偶数
线程1:奇数
线程2:偶数
对于这道题,很明显的是考察线程之间通信,即多个线程之间怎么阻塞、怎唤醒。
实现思路如下:
(1)开启两个线程,一个打印奇数,一个打印偶数;
(2)使用使用Object对象的wait()和notify()方法去实现当前线程的阻塞和目标线程的唤醒 (https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html)
实现代码
/**
* 奇数偶数打印
* 1、通过对象的wait和notify进行线程阻塞
* 2、通过对num%2的结果进行奇数偶数的判断输出
*
*/
public class JiOuOne {
private static volatile int num = 0;
private static final int max = 100;
public static void main(String[] args) {
String monitor = "monitor";
// 偶数线程
Thread oddThread = new Thread(new OddNumber(monitor));
oddThread.setName("偶数打印:");
// 奇数线程
Thread evenThread = new Thread(new EvenNumber(monitor));
evenThread.setName("奇数打印:");
oddThread.start();
evenThread.start();
}
/**
* 打印偶数
*/
static class OddNumber implements Runnable {
private String monitor;
public OddNumber(String monitor) {
this.monitor = monitor;
}
@Override
public void run() {
while (num <= max) {
synchronized (monitor) {
// 如果num%2有余数,则除不尽,则阻塞
while (num % 2 != 0) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "->" + num);
num++;
// 唤醒监视器
monitor.notify();
}
}
}
}
/**
* 打印奇数
*/
static class EvenNumber implements Runnable {
private String monitor;
public EvenNumber(String monitor) {
this.monitor = monitor;
}
@Override
public void run() {
while (num < max) {
synchronized (monitor) {
// 如果num%2余数为0,则可以除尽,阻塞
while (num % 2 == 0) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "->" + num);
num++;
// 唤醒对象监视器
monitor.notify();
}
}
}
}
}
打印结果如下: