控制线程顺序循环输出ABC (java Condition 代码简洁版)

来源:互联网 发布:淘宝移动端网址 编辑:程序博客网 时间:2024/06/05 02:50

面试题:

编写一个程序,开启3个线程,这3个线程的ID分别为ABC,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC.依次递推。


网上的很多代码都是依赖于静态计数变量,通过计数变量求模计算轮到哪个线程执行,而自然环境中当输出"A"后,很自然应该输出"B",并不需要知道当前输出的次数。

public class WaitNotifyTest01 {public static void main(String[] args) {new Thread(new Task("C")).start();new Thread(new Task("B")).start();new Thread(new Task("A")).start();}static class Task implements Runnable {static String[] ids = { "A", "B", "C" };static Lock lock = new ReentrantLock();static Map<String, Condition> conditionMap = new HashMap<String, Condition>() {{this.put("A", lock.newCondition());this.put("B", lock.newCondition());this.put("C", lock.newCondition());}};final int COUNT = 10;String id;int index;boolean isFirst=true;Task(String id) {this.id = id;this.index = indexOf(id);}@Overridepublic void run() {try {lock.lock();for (int i = 0; i < COUNT; i++) {//如果首次执行,让"A"先执行while(isFirst&&!id.equals(ids[0])){isFirst=false;conditionMap.get(id).await();}System.out.println(id);//唤醒下一个id的线程conditionMap.get(nextId()).signal();//循环到最后一次时不再等待if(i<COUNT-1){conditionMap.get(id).await();}}} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}private int indexOf(String id) {for (int i = 0; i < ids.length; i++) {if (id.equals(ids[i])) {return i;}}return -1;}private String nextId() {if (index == ids.length - 1) {return ids[0];}return ids[index+1];}}}



0 0