三个线程交替打印ABC
1. 使用Semaphore信号量实现线程同步
代码实现:
import java.util.concurrent.Semaphore;
public class PrinterTest {
public static void main(String[] args) {
Printer printer = new Printer(100);
Thread a = new Thread(printer::printA, "Thread A");
Thread b = new Thread(printer::printB, "Thread B");
Thread c = new Thread(printer::printC, "Thread C");
a.start();
b.start();
c.start();
}
}
class Printer {
// 使用Semaphore信号量实现线程同步
private Semaphore semaphoreA = new Semaphore(1);
private Semaphore semaphoreB = new Semaphore(0);
private Semaphore semaphoreC = new Semaphore(0);
private int num; // 打印数量
public Printer(int num) {
this.num = num;
}
public void printA() {
print('A', semaphoreA, semaphoreB);
}
public void printB() {
print('B', semaphoreB, semaphoreC);
}
public void printC() {
print('C', semaphoreC, semaphoreA);
}
public void print(char c, Semaphore currentSemaphore, Semaphore nextSemaphore) {
for (int i = 0; i < num; i++) {
try {
currentSemaphore.acquire(); // 阻塞当前线程
System.out.println(Thread.currentThread().getName() + ":" + c); // 打印字母
nextSemaphore.release(); // 唤醒下一个线程
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
2. 使用ReentrantLock + Condition实现线程同步
代码实现:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class PrinterTest {
public static void main(String[] args) {
Printer printer = new Printer(100);
Thread a = new Thread(printer::printA, "Thread A");
Thread b = new Thread(printer::printB, "Thread B");
Thread c = new Thread(printer::printC, "Thread C");
a.start();
b.start();
c.start();
// 先唤醒线程A对应的conditionA
printer.init();
}
}
class Printer {
// 使用ReentrantLock + Condition实现线程同步
private static ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
int threadIndex = 0; // 0:A,1:B, 2:C
private int num = 10; // 打印数量
public Printer(int num) {
this.num = num;
}
/**
* 初始时优先选择A
*/
public void init() {
lock.lock();
try {
conditionA.signal();
threadIndex = 0;
} finally {
lock.unlock();
}
}
public void printA() {
print(conditionA, conditionB, 0);
}
public void printB() {
print(conditionB, conditionC, 1);
}
public void printC() {
print(conditionC, conditionA, 2);
}
public void print(Condition currentCondition, Condition nextCondition, int currentIndex) {
for (int i = 0; i < num; i++) {
lock.lock(); // 加锁
try {
// 不是当前线程能打印的时机,阻塞当前线程
while (currentIndex != threadIndex) {
currentCondition.await();
}
char c = (char) ('A' + threadIndex);
System.out.println(Thread.currentThread().getName() + ":" + c);
threadIndex = (threadIndex + 1) % 3;
nextCondition.signal(); // 唤醒下一线程
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock(); // 解锁
}
}
}
}