Synchronization between threads

Because in previous work, single thread can solve the problem, and multi-threading is seldom used, even when used, it is encapsulated in some framework source code, so it has not been too concerned about this problem.

But two days ago, I came across a question about synchronization between multi-threads, so I took this opportunity to look at the relevant knowledge.

Relevant basic knowledge:

sleep(), wait(), notify(), notifyAll() methods are often used in multithreading. There are several points to note:
1. sleep() belongs to the Thread class, while wait(), notify(), notifyAll() belongs to the Object class.
2. After the call of sleep(), the program will pause the execution of the specified time and give the cpu resources to other threads. However, its monitoring status remains unchanged and the lock will not be released. When the specified time comes, the program will automatically resume its running state. wait() not only releases cpu resources, but also releases locks.
3. When wait() is executed with notify() and notifyAll (), the lock must be acquired first, so it is usually used with synchronized keywords.
4. When notify() and notify All () are executed, a thread waiting for the lock is awakened, and the execution continues until the synchronized block of code that exits the object lock is executed. [notify() and notifyAll() do not release the lock immediately after execution, but wait until the code in the critical area is executed before release. Therefore, in practical programming, we should try to call notify(), notifyAll(), immediately exit the critical zone. That is, don't write time-consuming code after notify(), notify All ()]

The above are some basic knowledge points about threads, with these knowledge paving the way, now let's look at the specific requirements of the topic:
There are three threads A, B and C. They print "morning", "noon" and "night". How to design the synchronization among these threads so that they can print the words "morning, noon and evening" 10 times in a row?
Here are a few lines of clumsy code written by Xiaobian on his own keyboard to achieve this function:

package com.monkey.testthreadasync;

public class TestThreadAsync {
    private static Thread threadA;
    private static Thread threadB;
    private static Thread threadC;
    private static int count = 0;
    private static int PRINT_COUNT = 10;
    private static boolean flagA = true;

    public static void main(String[] args) {
        testThreadAsync();
    }

    //Both notify and wait methods are object methods, and should be locked when calling both methods (otherwise, java.lang.IllegalMonitorStateException will occur)
    //That is to say, it is commonly used with synchronized keywords.
    private static void testThreadAsync() {
        Object objA = new Object();
        Object objB = new Object();
        Object objC = new Object();
        threadA = new Thread(){
            public void run() {
                while(flagA){
                    if(count>=PRINT_COUNT){
                        flagA = false;
                        continue;
                    }
                    synchronized (objA) {
                        System.out.println("Morning");
                        count++;
                        try {
                            if (threadB != null && threadB.isAlive()){
                                synchronized (objB) {
                                    objB.notify();
                                }
                            }else{
                                threadB.start();
                            }
                            objA.wait();
                        }catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };

        threadB = new Thread(){
            public void run() {
                while(true){
                    synchronized (objB) {
                        System.out.println("Noon");
                        if (threadC != null && threadC.isAlive()){
                            synchronized (objC) {
                                objC.notify();
                            }
                        }else{
                            threadC.start();
                        }
                        try {
                            objB.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        threadC = new Thread(){
            public void run() {
                while(true){
                    synchronized (objC) {
                        System.out.println("Night");
                        synchronized (objA) {
                            objA.notify();
                        }
                        try {
                            //Although threadA.notify() was executed earlier, the notify method does not release the lock immediately.
                            //Locks need to be released after the code behind notify has been executed, so the method behind notify should not perform time-consuming operations.
                            objC.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };

        threadA.start();
    }

}

The printing results are as follows. The functions required by the title are basically realized.

If there is any need for correction or optimization, please leave a message for discussion.^^^^

Keywords: Programming Java

Added by Twister1004 on Mon, 03 Jun 2019 23:06:05 +0300