面试遇到的一道面试题:三个线程循环有序输出10次ABCABC...
解决思路:使用synchronized,wait和notifyAll控制线程同步
package com.myj.test.thread;
/**
* 三个线程循环打印ABC10次
*
* 通过给实现Runnable接口的类添加一个私有变量,该变量就是每一个运行该任务线程的标识,
* 只有当线程的标识与Letter的私有变量一致才会运行输出,否则将阻塞,
* 直到其他线程将其唤醒,并在阻塞的位置继续执行,即再判断标识和letter的值
*
* letter的值也是需要改变的,每次线程输出完之后,要将该值更改为下一个
*
*
*/
public class ABC {
public static void main(String[] args) {
ABC t = new ABC();
Letter l = t.new Letter();
new Thread(t.new Mission(l, 'A')).start();
new Thread(t.new Mission(l, 'B')).start();
new Thread(t.new Mission(l, 'C')).start();
}
class Letter{
private char letter = 'A';
public void show(){
System.out.println(letter);
}
public void nextLetter(char letter){
switch(letter){
case 'A':
this.letter = 'B';
break;
case 'B':
this.letter = 'C';
break;
case 'C':
this.letter = 'A';
break;
}
}
public char getLetter(){
return this.letter;
}
}
class Mission implements Runnable{
private Letter letter;
//线程的标识
private char let;
public Mission(Letter letter, char let){
this.letter = letter;
this.let = let;
}
@Override
public void run() {
for(int i=0;i<10;i++){
synchronized(letter){
//运行的线程标识如果和letter的值不一样就先使该线程阻塞
//直到运行的线程标识和letter值一致
while(let!=letter.getLetter()){
try {
//进入阻塞,直到其他线程调用notifyAll唤醒,
//在此基础上继续运行,继续判断是否该轮到该线程输出
letter.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
letter.show();
letter.nextLetter(let);
letter.notifyAll();
}
}
}
}
}