三個線程分別打印A,B捐下,C持舆,要求這三個線程一起運行嘲碱,打印n次,輸出形如“ABCABCABC....”的字符串理卑。
1. 解法一:使用Lock
public class PrintABCUsingLock {
private int times;
private int state;
private Lock lock = new ReentrantLock();
public PrintABCUsingLock(int times) {
this.times = times;
}
public static void main(String[] args) {
PrintABCUsingLock printABC = new PrintABCUsingLock(10);
new Thread(printABC::printA).start();
new Thread(printABC::printB).start();
new Thread(printABC::printC).start();
}
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.print(name);
}
lock.unlock();
}
}
}
2. 解法二:使用wait/notify
public class PrintABCUsingWaitNotify {
private int times;
private volatile int state;
private static final Object LOCK = new Object();
public PrintABCUsingWaitNotify(int times) {
this.times = times;
}
public static void main(String[] args) {
PrintABCUsingWaitNotify printABC = new PrintABCUsingWaitNotify(10);
new Thread(printABC::printA).start();
new Thread(printABC::printB).start();
new Thread(printABC::printC).start();
}
public void printA() {
try {
print("A", 0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printB() {
try {
print("B", 1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printC() {
try {
print("C", 2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void print(String name, int targetState)
throws InterruptedException {
for (int i = 0; i < times; i++) {
synchronized (LOCK) {
while (state % 3 != targetState) {
LOCK.wait();
}
state++;
System.out.print(name);
LOCK.notifyAll();
}
}
}
}
解法三:使用Lock/Condition
public class PrintABCUsingLockCondition {
private int times;
private int state;
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition();
public PrintABCUsingLockCondition(int times) {
this.times = times;
}
public static void main(String[] args) {
PrintABCUsingLockCondition printABC = new PrintABCUsingLockCondition(10);
new Thread(printABC::printA).start();
new Thread(printABC::printB).start();
new Thread(printABC::printC).start();
}
public void printA() {
print("A", 0, conditionA, conditionB);
}
public void printB() {
print("B", 1, conditionB, conditionC);
}
public void printC() {
print("C", 2, conditionC, conditionA);
}
private void print(String name, int targetState, Condition current,
Condition next) {
for (int i = 0; i < times;) {
lock.lock();
try {
while (state % 3 != targetState) {
current.await();
}
state++;
i++;
System.out.print(name);
next.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
解法四:使用Semaphore
public class PrintABCUsingSemaphore {
private int times;
private Semaphore semaphoreA = new Semaphore(1);
private Semaphore semaphoreB = new Semaphore(0);
private Semaphore semaphoreC = new Semaphore(0);
public PrintABCUsingSemaphore(int times) {
this.times = times;
}
public static void main(String[] args) {
PrintABCUsingSemaphore printABC = new PrintABCUsingSemaphore(10);
new Thread(printABC::printA).start();
new Thread(printABC::printB).start();
new Thread(printABC::printC).start();
}
public void printA() {
try {
print("A", semaphoreA, semaphoreB);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printB() {
try {
print("B", semaphoreB, semaphoreC);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printC() {
try {
print("C", 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.print(name);
next.release();
}
}
}