Java multi-thread concurrent collaboration producer consumer Design Mode

Source: Internet
Author: User
IT information, Java multi-thread concurrent collaboration producer consumer design model, UDN Developer Forum, IT technology community focusing on enterprise Internet Development two threads one producer one consumer

Requirement scenario

Two threads, one for production, one for consumption, the producer for production, and the consumer for consumption

Problems Involved

Synchronization problem: how to ensure the integrity of the same resource when it is accessed by multiple threads concurrently. A common synchronization method is to use the tag or lock mechanism.

The wait ()/nofity () method is the two methods of the base class Object, which means that all Java classes will have these two methods, so that we can implement a synchronization mechanism for any Object.

Wait () method: When the buffer zone is full or empty, the producer/consumer thread stops its execution, gives up the lock, and puts itself in the wait state for other threads to execute.

Notify () method: When the producer/consumer puts/fetches a product from the buffer, it sends an executable notification to other waiting threads and gives up the lock to keep itself in the waiting state.

Code Implementation (three classes in total and a test class for the main method)

Resource. java/***** Created by yuandl on 2016-10-11. /*** Resource */public class Resource {/* Resource no. */private int number = 0;/* Resource flag */private boolean flag = false; /*** production resource */public synchronized void create () {if (flag) {// first judge whether the mark has been produced. if it has been produced, wait for consumption; try {wait (); // wait for the production thread} catch (InterruptedException e) {e. printStackTrace () ;}} number ++; // produce a System. out. println (Thread. currentThread (). getName () + "Producer ------------" + number); flag = true; // mark the resource as running y (); // wake up the thread waiting to operate the resource (Queue )} /*** consume resource */public synchronized void destroy () {if (! Flag) {try {wait ();} catch (InterruptedException e) {e. printStackTrace () ;}} System. out. println (Thread. currentThread (). getName () + "Consumer ***" + number); flag = false; Consumer y ();}}

Producer. java

/*** Created by yuandl on 2016-10-11. */*** Producer */public class Producer implements Runnable {private Resource resource; public Producer (Resource resource) {this. resource = resource;} @ Override public void run () {while (true) {try {Thread. sleep (10);} catch (InterruptedException e) {e. printStackTrace ();} resource. create ();}}}

Consumer. java

/*** Consumer */public class Consumer implements Runnable {private Resource resource; public Consumer (Resource resource) {this. resource = resource;} @ Override public void run () {while (true) {try {Thread. sleep (10);} catch (InterruptedException e) {e. printStackTrace ();} resource. destroy ();}}}

ProducerConsumerTest. java

/*** Created by yuandl on 2016-10-11. */public class ProducerConsumerTest {public static void main (String args []) {Resource resource = new Resource (); new Thread (new Producer (resource )). start (); // producer Thread new Thread (new Consumer (resource )). start (); // consumer thread }}

Print results

Thread-0 producer ---------- 1 Thread-1 consumer ***** 1 Thread-0 producer ---------- 2 Thread-1 consumer ***** 2 Thread-0 producer ---------- 3 Thread-1 consumer * *** 3 Thread-0 producer ---------- 4 Thread-1 consumer ***** 4 Thread-0 producer ---------- 5 Thread-1 consumer ***** 5 Thread-0 producer ------------ 6 Thread-1 consumer ***** 6 Thread-0 producer ---------- 7 Thread-1 consumer ***** 7 Thread-0 producer ------------ 8 Thread-1 consumer ***** 8 thread-0 producer ---------- 9 Thread-1 consumer ***** 9 Thread-0 producer ---------- 10 Thread-1 consumer ***** 10

The above printed results show that there is no problem


Problems with multiple threads, multiple producers, and multiple consumers

Requirement scenario

Four threads, two for production, two for consumption, one for producer, and one for consumer

Problems Involved

NotifyAll () method: When the producer/consumer puts/fetches a product from the buffer, it sends an executable notification to all other threads waiting for, and gives up the lock to keep itself in the waiting state.

Test code again

 

ProducerConsumerTest. java/***** Created by yuandl on 2016-10-11. */public class ProducerConsumerTest {public static void main (String args []) {Resource resource = new Resource (); new Thread (new Consumer (resource )). start (); // producer Thread new Thread (new Consumer (resource )). start (); // Producer Thread new Thread (new Producer (resource )). start (); // consumer Thread new Thread (new Producer (resource )). start (); // consumer thread }}

Running result

Thread-0 producer ---------- 100 Thread-3 consumer ***** 100 Thread-0 producer ---------- 101 Thread-3 consumer ***** 101 Thread-2 consumer ***** 101 Thread -1 Producer ------------ 102 Thread-3 consumer ***** 102 Thread-0 producer ---------- 103 Thread-2 consumer ***** 103 Thread-1 Producer ---------- 104 Thread-3 consumer * * ** 104 Thread-1 Producer ------------ 105 Thread-0 producer ------------ 106 Thread-2 consumer ***** 106 Thread-1 Producer ---------- 107 Thread-3 consumer ***** 107 thread-0 producer ---------- 108 Thread-2 consumer ***** 108 Thread-0 producer ---------- 109 Thread-2 consumer ***** 109 Thread-1 Producer ---------- 110 Thread-3 consumer * *** 110

Problems found through the above printed results


101 is produced once and consumed twice

105 production, but no consumption

Cause Analysis

When two threads simultaneously operate the producer production or consumer consumption, if either the producer or both threads are wait (), notify () Again (), because one of the threads has changed the mark and the other thread does not judge the mark when it is executed directly again.

If judgment mark, only once, will cause the thread that should not run to run. Data error occurs.

Solution

The while judgment mark solves the problem of whether the thread needs to run after obtaining the execution right! That is, when wait () is followed by notify (), the flag is judged again.

Code improvement (if-> while in Resource)

Resource. java

/*** Created by yuandl on 2016-10-11. /*** Resource */public class Resource {/* Resource no. */private int number = 0;/* Resource flag */private boolean flag = false; /*** production resource */public synchronized void create () {while (flag) {// first judge whether the mark has been produced. If it has been produced, wait for consumption; try {wait (); // wait for the production thread} catch (InterruptedException e) {e. printStackTrace () ;}} number ++; // produce a System. out. println (Thread. currentThread (). getName () + "producer ------ ------ "+ Number); flag = true; // mark the resource as running y (); // wake up the thread waiting for the resource (Queue )} /*** consume resource */public synchronized void destroy () {while (! Flag) {try {wait ();} catch (InterruptedException e) {e. printStackTrace () ;}} System. out. println (Thread. currentThread (). getName () + "Consumer ***" + number); flag = false; Consumer y ();}}

Discover problems again


Print to a value, such as 74 after production, and the program is stuck, as if it was locked.

Cause Analysis

Y: Only one thread can be awakened. If this thread is awakened, it makes no sense. Besides, the while flag + running y will lead to a "deadlock ".

Solution

NotifyAll solves the problem that the local thread will wake up the other thread.

Final code improvement (notify ()-> policyall () in Resource ())

Resource. java

/*** Created by yuandl on 2016-10-11. /*** Resource */public class Resource {/* Resource no. */private int number = 0;/* Resource flag */private boolean flag = false; /*** production resource */public synchronized void create () {while (flag) {// first judge whether the mark has been produced. If it has been produced, wait for consumption; try {wait (); // wait for the production thread} catch (InterruptedException e) {e. printStackTrace () ;}} number ++; // produce a System. out. println (Thread. currentThread (). getName () + "producer ------ ------ "+ Number); flag = true; // mark the resource as producing policyall (); // wake up the thread waiting for the resource (Queue )} /*** consume resource */public synchronized void destroy () {while (! Flag) {try {wait ();} catch (InterruptedException e) {e. printStackTrace () ;}} System. out. println (Thread. currentThread (). getName () + "Consumer ***" + number); flag = false; policyall ();}}

Running result

Thread-0 producer ---------- 412 Thread-2 consumer ***** 412 Thread-0 producer ---------- 413 Thread-3 consumer ***** 413 Thread-1 Producer ---------- 414 Thread-2 consumer * *** 414 Thread-1 Producer ---------- 415 Thread-2 consumer ***** 415 Thread-0 producer ---------- 416 Thread-3 consumer ***** 416 Thread-1 Producer ------------ 417 Thread-3 consumer ***** 417 Thread-0 producer ---------- 418 Thread-2 consumer ***** 418 Thread-0 producer ------------ 419 Thread-3 consumer ***** 419 thread-1 Producer ------------ 420 Thread-2 consumer ***** 420

The above is all done, and there is no problem

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.