目录
2 synchronized/wait/notifyAll 机制
3 ReentrantLock/Condition.await()/Condition.signalAll() 机制
1 思路
启动三个线程,采用多线程间等待/通知的机制来设计。维护一个全局不变数组printArr和变量索引index,printArr[index]就是接下来的线程要打印的字符。三个线程一开始就定好了打印的字符,当线程获取锁后,要判断printArr[index]与指定该线程的字符相等,相等就打印字符同时index = (index+1)%3,不相等表明还没轮到当前线程打印,当前线程等待。
2 synchronized/wait/notifyAll 机制
public class Test1 {
private static char[] printArr = new char[]{'a','b','c'};
private static volatile int index; // 保证index的可见性
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(3);
final Object lock = new Object();
threadPool.execute(new MyThread(lock,printArr[index]));
threadPool.execute(new MyThread(lock,printArr[index+1]));
threadPool.execute(new MyThread(lock,printArr[index+2]));
threadPool.shutdown();
}
private static class MyThread extends Thread{ // 静态内部打印类
Object lock; // 同步锁和等待/通知锁
char printC; // 指定的要打印的字符
MyThread(final Object lock ,char printC){
this.lock = lock;
this.printC = printC;
}
@Override
public void run(){
while(true){
synchronized (lock){
char c = printArr[index];
if (c == printC){
System.out.println(c);
index = (index+1)%printArr.length; // index“+1”
lock.notifyAll(); // 唤醒所有等待在lock上的线程
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
3 ReentrantLock/Condition.await()/Condition.signalAll() 机制
public class Test2 {
private static char[] printArr = new char[]{'a','b','c'};
private static volatile int index; // 保证index的可见性
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(3);
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
threadPool.execute(new MyThread(lock,condition,printArr[index]));
threadPool.execute(new MyThread(lock,condition,printArr[index+1]));
threadPool.execute(new MyThread(lock,condition,printArr[index+2]));
threadPool.shutdown();
}
private static class MyThread extends Thread{ // 静态内部打印类
ReentrantLock lock;
Condition condition;
char printC; // 指定的要打印的字符
MyThread(ReentrantLock lock ,Condition condition ,char printC){
if (lock == null || condition == null)
throw new NullPointerException("lock or condition is null");
this.lock = lock;
this.condition = condition;
this.printC = printC;
}
@Override
public void run(){
while(true){
lock.lock();
try {
char c = printArr[index];
if (c == printC){
System.out.println(c);
index = (index+1)%printArr.length;
condition.signalAll();
} else {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}finally {
lock.unlock();
}
}
}
}
}