Java -- thread communication

Posted by 8ennett on Fri, 28 Feb 2020 08:35:00 +0100

Java - thread communication

Article directory

concept

Thread communication concept: thread is an independent individual in the operating system, but these individuals cannot become a whole without special processing, and the communication between threads becomes one of the necessary ways of the whole. When there is communication command between threads, the interaction between the systems will be more powerful, which will not only improve the CPU utilization, but also enable developers to effectively control and supervise the thread tasks in the process of processing.

Introduce

Problem introduction: print 1-100 with two threads. Thread 1 and thread 2 print alternately.
Code:

package com.CharlesLC_Test;

public class Thread_Test2 {
    public static void main(String[] args) {
        Count demo = new Count();
        Thread count_num1 = new Thread(demo);
        Thread count_num2 = new Thread(demo);
        count_num1.setName("Thread one");
        count_num2.setName("Thread two");
        count_num1.start();
        count_num2.start();
    }
}
//Define subclass and implement Runnable interface
class Count implements Runnable{
    private int num;
    public void run() {
        while(true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (this) {
                if (num <= 100)
                    System.out.println(Thread.currentThread().getName() + ": " + num++);
                else
                    break;
            }
        }
    }
}

Without any measures, the output results are not output in sequence, because both threads are seizing the execution power of cpu, which is a probability:

wait() with notify() and notifyAll()

  • Wait(): causes the current thread to suspend and give up CPU, synchronize resources and wait, so that other threads can access and modify shared resources, while the current thread queues and waits for other threads to call notify() or notifyAll() method to wake up, and then waits for the ownership of the monitor to be regained before execution.
  • notify(): wakes up the highest priority thread waiting for synchronization resources to finish waiting
  • notifyAll(): wakes up all threads queued for resources to end waiting

Note: these three methods can only be used in synchronized method or synchronized code block, otherwise java.lang.legalmonitorstateexception will be reported.
Because these three methods must have lock Object calls, and any Object can be used as a synchronized lock, these three methods can only be declared in the Object class.

Using wait() and notify() to solve
Modify the Count class to include wait() and notify()

class Count implements Runnable{
    private int num;
    public void run() {
        while(true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (this) {
                notify();
                if (num <= 100) {

                    System.out.println(Thread.currentThread().getName() + ": " + num++);
                }
                else{break;}
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

The results are as follows (alternate output later):

Explanation: the result here shows that thread 2 enters the loop first, and first encounters synchronized. It gets the object lock, so thread 1 cannot enter. When thread 2 encounters notify(), because there is no thread being blocked, there is no need to do anything. When thread 2 outputs 0, it encounters a wait() thread 2 blocked, and releases the object lock. The thread can come in as soon as it encounters notify (), and it helps thread 2 to end the wait. Then when thread 1 encounters wait(), it waits for thread 2 to encounter notify () to end thread 1's wait (always after)

Producer and consumer models

Problem: the producer gives the product to the Clerk, while the consumer takes the product from the Clerk. The Clerk can only hold a fixed number of products (such as 20) at a time. If the producer tries to produce more products, the Clerk will ask the producer to stop. If there is a vacancy in the shop, the producer will be informed to continue to produce; if there is no vacancy in the shop When the product is ready, the Clerk will tell the consumer to wait a moment. If there is a product in the store, the Clerk will inform the consumer to take it.

  • There are two possible problems:
    When the producer is faster than the consumer, the consumer will miss some data.
    When the consumer is faster than the producer, the consumer will take the same data.

There is communication in this example:
The code is as follows (synchronized + wait notify mode):

package com.charlesLC_thread;

public class ProduceTest {
    public static void main(String[] args) {
        Clerk demo = new Clerk();
        Customer customer = new Customer(demo);
        Producer producer = new Producer(demo);
        customer.setName("I am a consumer:");
        producer.setName("I am a producer:");
        producer.start();
        customer.start();

    }
}

class Clerk{
    private int num;
    public  synchronized void  getproduce() {
        if (num<20){
            notify();
            num++;
            System.out.println(Thread.currentThread().getName() + "Start production"+num+"A product");
        }
        else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void costproduce() {
        if (num>0){
            notify();
            System.out.println(Thread.currentThread().getName()+"Start consuming"+num+"A product");
            num--;
        }
        else{
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Customer extends  Thread{
    private  Clerk clerk;
    public  Customer(Clerk clerk ){
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println("Start consuming products");
        while(true){
            clerk.costproduce();
            try {
                sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class  Producer extends Thread{
    private Clerk clerk;

    public Producer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println("Start production");
        while (true){
            try {
                sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.getproduce();
        }
    }
}

The results are as follows:

Published 11 original articles · praised 8 · visited 1429
Private letter follow

Topics: Java