Java经典线程问题:三个打印机轮流打字

题目: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
本文分类: 100 java
欢迎评论
共5条评论和回复
{{comment.createTime | simpleDateHourMinute}}
{{comment.content}}
{{subComment.name}} (作者) {{subComment.name}} {{subComment.content}}