题目:A, B, C三个打印机,每个打印机是一个线程,要求让A,B,C轮流打印自己的名字,每个打四次。
分析:这道题其实就是考察的java中多线程通信。在给出代码之前,稍微复习一下java中线程通信的关键方法。
Object
中提供了三个方法:wait()
,notify()
,notifyAll()
,这三个方法必须由同步监视器来调用。
1.对于使用synchronized
修饰的同步方法,因为该类的默认实例(this)就是同步监视器,所以可以在同步方法中直接调用这三个方法
2.对于使用synchronized
修饰的同步代码块,同步监视器是synchronized
后括号里的对象,所以必须使用该对象调用这三个方法。
这三个方法的解释如下:wait()
:导致当前线程等待,直到其他线程调用该同步监视器的notify()方法或者notifyAll()方法来唤醒该线程。notify()
:唤醒在此同步监视器上等待的单个线程。如果所有线程都在此同步监视器上等待,则会任意选择唤醒其中一个线程。notifyAll()
:唤醒在此同步监视器上等待的所有线程。
有了上面的关于线程通信的基础知识,可以很容易写出如下代码:
public class Printer extends Thread {
private String msg;
private Printer next;
public Printer(String msg) {
this.msg = msg;
}
@Override
public void run() {
for (int i = 1; i < 5; i++) {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第" + i + "次:" + this.msg);
synchronized (this.next) {
this.next.notify();
}
}
}
}
public static void main(String[] args) {
Printer A = new Printer("A");
Printer B = new Printer("B");
Printer C = new Printer("C");
A.next = B;
B.next = C;
C.next = A;
A.start();
B.start();
C.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (A) {
A.notify();
}
}
}
代码执行结果如下:
第1次:A
第1次:B
第1次:C
第2次:A
第2次:B
第2次:C
第3次:A
第3次:B
第3次:C
第4次:A
第4次:B
第4次:C