使用Lock实现
public class PrintABC {
private int times;//控制打印的次数
private int state; //控制当前的状态保证之间交替打印
private Lock lock = new ReentrantLock();//保证每次只能一个线程能够拿到资源
public PrintABC(int times) {
this.times = times;
}
public void printA() {
print("A", 0);
}
public void printB() {
print("B", 1);
}
public void printC() {
print("C", 2);
}
private void print(String name, int targetState) {
for (int i = 0; i < times; ) {
lock.lock();
if (state % 3 == targetState) {
state++;
i++;
System.out.println("线程:" + name + ",第 " + i + " 打印");
}
lock.unlock();
}
}
public static void main(String[] args) {
PrintABC printABC = new PrintABC(10);
new Thread(printABC::printA).start();
new Thread(printABC::printB).start();
new Thread(printABC::printC).start();
}
}
使用Semaphore实现
public class PrintABC {
private int times;
private Semaphore semaphoreA = new Semaphore(1);
private Semaphore semaphoreB = new Semaphore(0);
private Semaphore semaphoreC = new Semaphore(0);
public PrintABC(int times) {
this.times = times;
}
public void printA() {
try {
print("A", semaphoreA, semaphoreB);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printB() {
try {
print("A", semaphoreB, semaphoreC);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printC() {
try {
print("A", semaphoreC, semaphoreA);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void print(String name, Semaphore current, Semaphore next) throws InterruptedException {
for (int i = 0; i < times; i++) {
current.acquire();
System.out.println("线程:" + name + ",第 " + i + " 打印");
next.release();
}
}
public static void main(String[] args) {
PrintABC printABC = new PrintABC(10);
new Thread(printABC::printA).start();
new Thread(printABC::printB).start();
new Thread(printABC::printC).start();
}
}
交替打印012
输入:n = 2
输出:“0102”
说明:三条线程异步执行,其中一个调用 zero(),另一个线程调用 even(),最后一个线程调用odd()。正确的输出为 “0102”。
class ZeroEvenOdd {
private int n;
private Semaphore semaphore0 = new Semaphore(1);
private Semaphore semaphoreOdd = new Semaphore(0);
private Semaphore semaphoreEven = new Semaphore(0);
public ZeroEvenOdd(int n) {
this.n = n;
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void zero(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= n; i++) {
semaphore0.acquire();
printNumber.accept(0);
if (i % 2 != 0) {
semaphoreOdd.release();
}else {
semaphoreEven.release();
}
}
}
public void even(IntConsumer printNumber) throws InterruptedException {
for (int i = 2; i <= n; i+= 2) {
semaphoreEven.acquire();
printNumber.accept(i);
semaphore0.release();
}
}
public void odd(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= n; i+= 2) {
semaphoreOdd.acquire();
printNumber.accept(i);
semaphore0.release();
}
}
}