按序打印——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的再理解

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

1114-按序打印

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

LeetCode 多线程练习1(1114. 按序打印 / 1115. 交替打印FooBar)

多线程按序交替打印