Finally understand thoroughly! A graphical understanding of Java multi-threaded case of producers and consumers of design patterns

Before reading suggestions

If the paper needs to have a more profound understanding of the recommendations look thread-safe, thread deadlocks, and related knowledge-thread communication, if you already have sufficient knowledge of these, I believe you must read this blog rewarding!

Depth understanding of Java threads - Banks owe me four million! ! !

One minute illustration of the Java thread deadlock with a bedtime story

First, the design scene

 Existing two threads, the thread is to effect character string 'A' 'B' 'C ' 'D' 'E' or 'F' 'G' 'H ' 'I' 'J' into the container Array List ( ) in, but in order to ensure the safety of the thread, you can only make one thread access, so each thread must acquire the lock to the critical resource object that is labeled container to access the object, and then perform data storage operations;
 however, each thread of each five times the number of characters stored, and the container can only be stored in four strings, when the fifth string thread into the container, to prevent abnormal procedures, the thread will wait indefinitely into the queue, and notify the access to data consumers;
 Similarly, a plurality of consumers, but also have access to data qualify lock mark, assuming a consumer consumer; consumers access to data, takes out a hypothesis, when the container when the data has been taken in order to ensure the security thread, the thread will wait indefinitely into the queue, and notify the producer of data stored;
Here Insert Picture Description
 the whole process is java thread design patterns between producers and consumers;

Second, the introduction of producers and consumers

 You first need to understand the nature of producers and consumers are thread, a number of producers in the production of products that will be available to take a number of consumer spending, in order to make producers and consumersConcurrent executionIn between the two set up a buffer capable of storing a plurality of products, producers will produce the product into the buffer, consumer products removed from the buffer for consumption, obviously must be between producers and consumers to keep pace, not only does not allow consumers to an empty buffer removal products, but also allow the producer to add products to a full buffer.

Third, the scenario reproduction code

 First, the need to create a container class Queue, the maximum capacity of the container 4, the type is ArrayListthe type of container provides two methods, a method is stored offer(), provided to the producer thread calls; Another method is to remove poll(), to the consumer thread calls ; to meet maintain synchronization between producers and consumers, each method must do three things:

  • 1. To ensure thread safety, must be locked container, that can only make the thread holding the lock tag access; At this method requires a synchronizedmodification;
  • 2. When the container is full or empty time (size == 0 or size == 4), the corresponding thread into the consumer or consumer thread waits indefinitely, calling the wait()method;
  • Or less than 3. When the container is not empty, the corresponding notification consumers added producers to produce, a corresponding notification producer consumer spending removed;

Here Insert Picture Description

Simulation data buffer area

//我的队列
class MyQueue {

    private List values = new ArrayList();

    private int max = 4;

    //存入队列
    public synchronized void offer(Object o){//E

        while(values.size() == max){
            //进来线程,停下
            try {
                this.wait();
                //被唤醒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notifyAll();
		values.add(o);
        System.out.println(Thread.currentThread().getName() + "存入元素 : "+ values );
    }

    //从队列取出
    public synchronized Object poll(){//1个元素

        while(values.size() == 0){
            try {
                this.wait();
                //被唤醒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.notifyAll();//唤醒因mq对象而进入无限期等待的线程对象(一个)

        return values.remove(0);
    }
}

Producers simulation

 The producer is essentially a thread here uses two producers, namely multi-threaded access, a critical resource object Queue, only the thread holding the lock mark when the object can access the object, and then the appropriate action.

//生产者1
class Produce1 extends Thread{
    MyQueue mq;
    public Produce1(MyQueue mq){
        this.mq = mq;
    }

    public void run(){
        System.out.println("Produce1启动");
        for (char ch = 'A'; ch <= 'E'; ch++) {
            mq.offer(ch);
        }
        System.out.println("Produce1结束");
    }
}
//生产者2
class Produce2 extends Thread{
    MyQueue mq;
    public Produce2(MyQueue mq){
        this.mq = mq;
    }

    public void run(){
        System.out.println("Produce2启动");
        for (char ch = 'F'; ch <= 'J'; ch++) {
            mq.offer(ch);
        }
        System.out.println("Produce2结束");
    }
}

Consumers simulation

 Consumers also a thread on the nature, of course, consumers can have the same producers as multiple, similar, only those with the lock-labeled consumer threads have the right to operate critical resource object; For convenience, consider a consumer;

//消费者
class Consumer extends Thread{
    MyQueue mq;
    public Consumer(MyQueue mq){
        this.mq = mq;
    }

    public void run(){
        for (int i = 0 ; i < 10 ; i++) {//循环取数据
            System.out.println(mq.poll() + "被移除");
        }
    }
}

The main function

 The main function is to let all threads started can be!

public static void main(String[] args) {

    MyQueue mq = new MyQueue();

    Produce1 p1 = new Produce1(mq);
    Produce2 p2 = new Produce2(mq);
    Consumer c1 = new Consumer(mq);

    p1.start();
    p2.start();
    c1.start();


    System.out.println("main end");
}

operation result

Here Insert Picture Description
 Clearly print the results have been very clear throughout the process tells us consumers and producers concurrent execution, I believe your mind has formed an animated picture, I hope you understand there is help! Of course, if convenient, please encourage your thumbs! Greatful!

Published 84 original articles · won praise 126 · views 120 000 +

Guess you like

Origin blog.csdn.net/qq_44717317/article/details/104884787