面试题:有 3 个独立的线程,一个只会输出 A,一个只会输出 B,一个只会输出 C,在三个线程启动的情况下,请用合理的方式让他们按顺序打印 ABC。
使用lock,Condition
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ABC {
//可重入锁
private final static Lock lock = new ReentrantLock();
//判断是否执行:1表示应该A执行,2表示应该B执行,3表示应该C执行
private static int state = 1;
//condition对象
private static Condition a = lock.newCondition();
private static Condition b = lock.newCondition();
private static Condition c = lock.newCondition();
public static void printA() {
//通过循环,hang住线程
for (int i = 0; i < 10; i++) {
try {
//获取锁
lock.lock();
//并发情况下,不能用if,要用循环判断等待条件,避免虚假唤醒
while (state != 1) {
a.await();
}
System.out.print("A");
state = 2;
b.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//要保证不执行的时候,锁能释放掉
lock.unlock();
}
}
}
public static void printB() throws InterruptedException {
for (int i = 0; i < 10; i++) {
try {
lock.lock();
//获取到锁,应该执行
while (state != 2) {
b.await();
}
System.out.print("B");
state = 3;
c.signal();
} finally {
lock.unlock();
}
}
}
public static void printC() throws InterruptedException {
for (int i = 0; i < 10; i++) {
try {
lock.lock();
while (state != 3) {
c.await();
}
//获取到锁,应该执行
System.out.print("C");
state = 1;
a.signal();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
ABC.printA();
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
try {
ABC.printB();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B").start();
new Thread(new Runnable() {
@Override
public void run() {
try {
ABC.printC();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "C").start();
}
}