目录
1 思路
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();
}
}
}
}
}
【【Java多线程实战设计】用三个线程按顺序循环打印abc三个字母,比如abcabcabc】
推荐阅读
- 线程多对多交替打印-condition
- 启动多个线程并按顺序执行
- java|使用线程Thread和Runnable输出1到100之间的偶数
- java多线程轮流打印数据问题
- Java|面试必问!Java 多线程中两个线程交替执行,一个输出偶数,一个输出奇数
- java多线程(循环输出ABC)
- JAVA并发编程——Callable接口和FutureTask简介和使用
- 多线程(至少三个线程)分别打印A、B、C,要求按ABC的顺序循环打印10次。