启动3个线程,3个线程的名字分别是A,B,C,每个线程将自己的名称在屏幕上打印5遍,打印顺序的ABCABC.....
分析:
这个题的思路和我的上一篇博客https://blog.****.net/huaijiu123/article/details/86370451这个题的思路是相同的,都是利用信号量来解决。
不同的是:
- 要将notify()换成notifyAll(),这是为什么呢?
万一A打印完之后,你只唤醒了C而没唤醒B,这就会产生死锁,所以要唤醒所有线程。 - 3个线程同时启动后,如果是C先进,这时flag都是1,但先打印的是C,后边只是控制了打印的顺序。要确保A一定先打印,就必须让A走A方法,B走B方法,C走C方法。这时就算C先进去,但它只能进printC()方法,此时flag == 1,它是不能打印C的,得等。
package www.java.test;
import java.io.OutputStream;
class Print{
int flag = 1;
int count = 0;
public int getCount() {
return count;
}
public synchronized void printA(){
while(flag != 1){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
count++;
flag = 2;
notifyAll();
}
public synchronized void printB(){
while(flag != 2){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
count++;
flag = 3;
notifyAll();
}
public synchronized void printC(){
while(flag != 3){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
count++;
flag = 1;
notifyAll();
}
}
class MyThread implements Runnable{
private Print print;
public MyThread(Print print) {
this.print = print;
}
@Override
public void run() {
while(print.getCount() < 16){//确保每个打印5遍
if(Thread.currentThread().getName().equals("A")){
print.printA();
}else if(Thread.currentThread().getName().equals("B")){
print.printB();
}else if(Thread.currentThread().getName().equals("C")){
print.printC();
}
}
}
}
public class Test{
public static void main(String[] args) {
Print print = new Print();
MyThread mt = new MyThread(print);
Thread th1 = new Thread(mt,"A");
Thread th2 = new Thread(mt,"B");
Thread th3 = new Thread(mt,"C");
th1.start();
th2.start();
th3.start();
}
}