按序打印——wait的再理解

Posted 无赖H4

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按序打印——wait的再理解相关的知识,希望对你有一定的参考价值。

按序打印

我们提供了一个类:

public class Foo {
public void first() { print(“first”); }
public void second() { print(“second”); }
public void third() { print(“third”); }
}
三个不同的线程 A、B、C 将会共用一个 Foo 实例。

一个将会调用 first() 方法
一个将会调用 second() 方法
还有一个将会调用 third() 方法
请设计修改程序,以确保 second() 方法在 first() 方法之后被执行,third() 方法在 second() 方法之后被执行。
LeetCode按序打印

思路:
通过一个静态属性保留上一次打印的数字,然后加锁判断保证按序打印

加锁

 
public class Demo2 {
    private static int lastPrinted = 3;


    static class A extends Thread {
        @Override
        public void run() {
            while (true) {
                while (true) {
                    synchronized (Demo2.class) {
                        if (lastPrinted == 3) {
                            break;
                        }
                    }
                }
                System.out.println(1);
                lastPrinted = 1;
            }
        }
    }

    static class B extends Thread {
        @Override
        public void run() {
            while (true) {
                while (true) {
                    synchronized (Demo2.class) {
                        if (lastPrinted == 1) {
                            break;
                        }
                    }
                }
                System.out.println(2);
                lastPrinted = 2;
            }
        }
    }

    static class C extends Thread {
        @Override
        public void run() {
            while (true) {
                while (true) {
                    synchronized (Demo2.class) {
                        if (lastPrinted == 2) {
                            break;
                        }
                    }
                }
                System.out.println(3);
                lastPrinted = 3;
            }
        }
    }


    public static void main(String[] args) {
        Thread a = new Demo2.A();
        Thread b = new Demo2.B();
        Thread c = new Demo2.C();
        a.start();
        b.start();
        c.start();
    }
}

volatile

通过volatile修饰,避免因为内存可见性出现的问题(缓存问题),
但是还是会造成cpu空转

public class Demo1 {
    private static volatile int lastPrinted = 3;


    static class A extends Thread {
        @Override
        public void run() {
            while (true) {
                while (lastPrinted != 3) {
                }
                System.out.println(1);
                lastPrinted = 1;
            }
        }
    }

    static class B extends Thread {
        @Override
        public void run() {
            while (true) {
                while (lastPrinted == 1) {
                }
                System.out.println(2);
                lastPrinted = 2;
            }
        }
    }

    static class C extends Thread {
        @Override
        public void run() {
            while (true) {
                while (lastPrinted == 2) {
                }
                System.out.println(3);
                lastPrinted = 3;
            }
        }
    }


    public static void main(String[] args) {
        Thread a = new Demo2.A();
        Thread b = new Demo2.B();
        Thread c = new Demo2.C();
        a.start();
        b.start();
        c.start();
    }
}

wait

package 按序打印;


import timer.Demo;

public class Demo3 {
    private static volatile int lastPrinted = 3;


    static class A extends Thread {
        @Override
        public void run() {
            try {
                while (true) {
                    while (lastPrinted != 3) {
                        synchronized (Demo3.class) {
                            if (lastPrinted != 3) {
                                Demo3.class.wait();
                            }
                        }
                    }
                    System.out.println(1);
                    lastPrinted = 1;
                    synchronized (Demo.class) {
                        Demo3.class.notifyAll();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class B extends Thread {
        @Override
        public void run() {
            try {
                while (true) {
                    while (lastPrinted != 1) {
                        synchronized (Demo3.class) {
                            if (lastPrinted != 1) {
                                Demo3.class.wait();
                            }
                        }
                    }
                    System.out.println(2);
                    lastPrinted = 2;
                    synchronized (Demo.class) {
                        Demo3.class.notifyAll();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class C extends Thread {
        @Override
        public void run() {
            try {
                while (true) {
                    while (lastPrinted != 2) {
                        synchronized (Demo3.class) {
                            if (lastPrinted != 2) {
                                Demo3.class.wait();
                            }
                        }
                    }
                    System.out.println(3);
                    lastPrinted = 3;
                    synchronized (Demo.class) {
                        Demo3.class.notifyAll();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args) {
        Thread a = new Demo2.A();
        Thread b = new Demo2.B();
        Thread c = new Demo2.C();
        a.start();
        b.start();
        c.start();
    }
}

oj

package 按序打印;

/**
 *
 */
public class Foo {

    private int step = 3;

    public Foo() {
    }

    public void first(Runnable printFirst) throws InterruptedException {

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

    public void second(Runnable printSecond) throws InterruptedException {
        while (step != 1) {
            synchronized (this) {
                if (step != 1) {
                    wait();
                }
            }
        }
        // printSecond.run() outputs "second". Do not change or remove this line.
        printSecond.run();
        step = 2;
        synchronized (this) {
            notifyAll();
        }
    }

    public void third(Runnable printThird) throws InterruptedException {
        while (step != 2) {
            synchronized (this) {
                if (step != 2) {
                    wait();
                }
            }
        }
        // printThird.run() outputs "third". Do not change or remove this line.
        printThird.run();
        step = 3;
        synchronized (this) {
            notifyAll();
        }
    }
}

以上是关于按序打印——wait的再理解的主要内容,如果未能解决你的问题,请参考以下文章

按序打印——wait的再理解

1114. 按序打印笔记

1114. 按序打印笔记

多线程按序交替打印

java多线程:结合多线程交替打印10次abc实例,对wait/notify使用的彻底理解

JUC-Condition和Lock实践-线程按序交替执行