欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

按序打印

程序员文章站 2022-07-14 08:02:24
...

按序打印

按序打印

一开始这样写的,错了,大家知道为什么吗?

class Foo {

    private int volatile n = 0;
    public Foo() {

    }

    public void first(Runnable printFirst) throws InterruptedException {

        synchronized (this){
            if(n % 3 == 0){
                // printFirst.run() outputs "first". Do not change or remove this line.
                printFirst.run();
                n += 1;
                notifyAll();
            }else {
                wait();
            }
        }

    }

    public void second(Runnable printSecond) throws InterruptedException {

        synchronized (this) {
            if (n % 3 == 1) {
                // printSecond.run() outputs "second". Do not change or remove this line.
                printSecond.run();
                n += 1;
                notifyAll();
            } else {
                wait();
            }
        }
    }

    public void third(Runnable printThird) throws InterruptedException {

        synchronized (this) {
            if (n % 3 == 2) {
                // printThird.run() outputs "third". Do not change or remove this line.
                printThird.run();
                n += 1;
                notifyAll();
            } else {
                wait();
            }
        }
    }
}

 其实错就错在:

else {
       wait();
            }

这里了,因为如果second和third先执行,然后first执行,导致只能输出first,不能输出second和third,因为wait被notify后,不会再次执行函数体。

改成下面的代码就ok了:

package 多线程;

class Foo {

    private volatile  int n = 0;
    public Foo() {

    }

    public void first(Runnable printFirst) throws InterruptedException {

        synchronized (this){
            while(n % 3 != 0){
                wait();
            }
            if(n % 3 == 0){
                // printFirst.run() outputs "first". Do not change or remove this line.
                printFirst.run();
                n += 1;
                notifyAll();
            }
        }

    }

    public void second(Runnable printSecond) throws InterruptedException {

        synchronized (this) {

            while(n % 3 != 1){
                wait();
            }
            if (n % 3 == 1) {
                // printSecond.run() outputs "second". Do not change or remove this line.
                printSecond.run();
                n += 1;
                notifyAll();
            }
        }
    }

    public void third(Runnable printThird) throws InterruptedException {

        synchronized (this) {

            while(n % 3 != 2){
                wait();
            }
            if (n % 3 == 2) {
                // printThird.run() outputs "third". Do not change or remove this line.
                printThird.run();
                n += 1;
                notifyAll();
            }
        }
    }

    public static void main(String[] args) {
        Foo foo = new Foo();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    foo.first();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    foo.second();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    foo.third();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

这里能够保证,拿到锁,继续执行下面的方法。

 while(n % 3 != 1){
                wait();
            }

按序打印

 

上一篇: 二分搜索

下一篇: 三数之和