问题: 开启3个线程,循环打印输出结果ABC (必须按照ABC的顺序显示) 10次
结果:
Thread-0 A
Thread-1 B
Thread-2 C
Thread-0 A
Thread-1 B
Thread-2 C
Semaphore
private static void testPrintABC5() {
PrintABC printABC = new PrintABC();
new Thread(() -> {
for (int i = 0; i < 2; i++) {
printABC.printA();
}
}).start();
new Thread(() -> {
for (int i = 0; i < 2; i++) {
printABC.printB();
}
}).start();
new Thread(() -> {
for (int i = 0; i < 2; i++) {
printABC.printC();
}
}).start();
}
static class printABC{
private Semaphore semaphoreA = new Semaphore(1);
private Semaphore semaphoreB = new Semaphore(0);
private Semaphore semaphoreC = new Semaphore(0);
public void printA() {
try {
semaphoreA.acquire();
System.out.println(Thread.currentThread().getName() + " A");
semaphoreB.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printB() {
try {
semaphoreB.acquire();
System.out.println(Thread.currentThread().getName() + " B");
semaphoreC.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printC() {
try {
semaphoreC.acquire();
System.out.println(Thread.currentThread().getName() + " C");
semaphoreA.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Synchronized
private static void testPrintABC1() {
new Thread(new PrintABC(0)).start();
new Thread(new PrintABC(1)).start();
new Thread(new PrintABC(2)).start();
}
static class PrintABC implements Runnable {
private static final Object lock = new Object();
private static volatile int count = 0;
private final int flag;
public PrintABC(int flag) {
this.flag = flag;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
while (count % 3 != flag) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + (char) (flag + 'A'));
count++;
lock.notifyAll();
}
}
}
}
Lock Condition
private static void testPrintABC2() {
new Thread(new PrintABC2(0)).start();
new Thread(new PrintABC2(1)).start();
new Thread(new PrintABC2(2)).start();
}
static class PrintABC2 implements Runnable {
public static final Lock lock = new ReentrantLock();
public static final Condition condition = lock.newCondition();
private static volatile int count = 0;
private final int flag;
public PrintABC2(int flag) {
this.flag = flag;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
lock.lock();
try {
while (count % 3 != flag) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + (char) (flag + 'A'));
count++;
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
Lock Multi Condition
private static void testPrintABC3() {
PrintABC3 printABC3 = new PrintABC3();
new Thread(() -> {
for (int i = 0; i < 2; i++) {
printABC3.printA();
}
}).start();
new Thread(() -> {
for (int i = 0; i < 2; i++) {
printABC3.printB();
}
}).start();
new Thread(() -> {
for (int i = 0; i < 2; i++) {
printABC3.printC();
}
}).start();
}
static class PrintABC3 {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
private int num = 0;
public void printA() {
lock.lock();
try {
while (num != 0) {
condition1.await();
}
System.out.println(Thread.currentThread().getName() + " A");
num = 1;
condition2.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printB() {
lock.lock();
try {
while (num != 1) {
condition2.await();
}
System.out.println(Thread.currentThread().getName() + " B");
num = 2;
condition3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printC() {
lock.lock();
try {
while (num != 2) {
condition3.await();
}
System.out.println(Thread.currentThread().getName() + " C");
num = 0;
condition1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
AtomicInteger
private static void testPrintABC4() {
new PrintABC4(0).start();
new PrintABC4(1).start();
new PrintABC4(2).start();
}
static class PrintABC4 extends Thread {
private final int flag;
private static AtomicInteger atomicInteger = new AtomicInteger(0);
public PrintABC4(int flag) {
this.flag = flag;
}
@Override
public void run() {
for (int i = 0; i < 2; i++) {
synchronized (atomicInteger) {
while (atomicInteger.get() % 3 != flag) {
try {
atomicInteger.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + (char) (flag + 65));
atomicInteger.getAndIncrement();
atomicInteger.notifyAll();
}
}
}
}