问题描述:写两个线程打印 1-100,⼀个线程打印奇数,⼀个线程打印偶数。
1. synchronized+wait/notify 实现
代码实现
public class ParityPrinter {
/**
* 最⼤打印数值,由构造函数传⼊
*/
private final int max;
/**
* 从 1 开始的计数器,⽤于追踪当前打印到的数字。
*/
private int count = 1;
/**
* 锁对象,用于线程间的通信
*/
private final Object lock = new Object();
public ParityPrinter(int max) {
this.max = max;
}
/**
* 打印偶数
*/
public void printOdd() {
print(true);
}
/**
* 打印奇数
*/
public void printEven() {
print(false);
}
/**
* 控制线程交替打印奇偶数值的方法。
* 通过共享锁对象和count变量实现线程间同步与协作。
*
* @param isOdd 布尔值标识,true表示当前线程负责打印奇数值,false表示打印偶数值
* @return 无返回值
*/
private void print(boolean isOdd) {
for (int i = 0; i < max; i++) {
synchronized (lock) {
// 等待直到count的奇偶状态与当前线程职责匹配
// 通过循环检测避免虚假唤醒问题
while (count % 2 == (isOdd ? 1 : 0)) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " : " + count++);
// 唤醒等待在锁对象上的其他线程
// 确保线程间交替执行顺序
lock.notify();
}
}
}
public static void main(String[] args) {
ParityPrinter parityPrinter = new ParityPrinter(100);
new Thread(parityPrinter::printOdd, "偶数打印线程").start();
new Thread(parityPrinter::printEven, "奇数打印线程 ").start();
}
}
2. Semaphore 实现
import java.util.concurrent.Semaphore;
public class ParityPrinter {
/**
* 最⼤打印数值,由构造函数传⼊
*/
private final int max;
/**
* 从 1 开始的计数器,⽤于追踪当前打印到的数字。
*/
private int count = 1;
/**
* 初始为1,奇数线程先获取
*/
private final Semaphore evenSemaphore = new Semaphore(1);
/**
* 初始为0,偶数线程等待
*/
private final Semaphore oddSemaphore = new Semaphore(0);
public ParityPrinter(int max) {
this.max = max;
}
/**
* 打印偶数
*/
public void printOdd() {
print(oddSemaphore, evenSemaphore);
}
/**
* 打印奇数
*/
public void printEven() {
print(evenSemaphore, oddSemaphore);
}
/**
* 打印线程名称和递增计数器,通过信号量控制线程的交替执行顺序。
*
* @param currentSemaphore 控制当前线程执行的信号量,获取许可后允许打印
* @param nextSemaphore 下一个线程关联的信号量,释放许可以允许其执行
* @return 无返回值
*/
private void print(Semaphore currentSemaphore, Semaphore nextSemaphore) {
for (int i = 0; i < max; i++) {
try {
//获取当前线程的信号量许可
currentSemaphore.acquire();
System.out.println(Thread.currentThread().getName() + " : " + count++);
//释放下一个信号量的许可以激活后续线程
nextSemaphore.release();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) {
ParityPrinter printer = new ParityPrinter(100);
new Thread(printer::printOdd, "偶数打印线程").start();
new Thread(printer::printEven, "奇数打印线程 ").start();
}
}
2612

被折叠的 条评论
为什么被折叠?



