


Java multi-threaded concurrent collaborative producer-consumer design pattern
Nov 21, 2016 pm 01:31 PM Two threads, one producer and one consumer
Demand scenario
Two threads, one responsible for production and one responsible for consumption, one producer produces and one consumer consumes
Issues involved
Synchronization issues: how to ensure the same Integrity when resources are accessed concurrently by multiple threads. Commonly used synchronization methods are to use marking or locking mechanisms. The wait() / nofity() methods are two methods of the base class Object, which means that all Java classes will have these two methods. In this way, we can Any object implements a synchronization mechanism.
Wait() method: When the buffer is full/empty, the producer/consumer thread stops its own execution, gives up the lock, puts itself in a wait state, and allows other threads to execute.
Notify() method: When the producer/consumer puts/takes out a product from the buffer, it sends an executable notification to other waiting threads, and at the same time gives up the lock and puts itself in a waiting state.
Code implementation (a total of three classes and a test class with main method)
Resource.java /** * Created by yuandl on 2016-10-11./** * 資源 */ public class Resource { /*資源序號*/ private int number = 0; /*資源標記*/ private boolean flag = false; /** * 生產(chǎn)資源 */ public synchronized void create() { if (flag) {//先判斷標記是否已經(jīng)生產(chǎn)了,如果已經(jīng)生產(chǎn),等待消費; try { wait();//讓生產(chǎn)線程等待 } catch (InterruptedException e) { e.printStackTrace(); } } number++;//生產(chǎn)一個 System.out.println(Thread.currentThread().getName() + "生產(chǎn)者------------" + number); flag = true;//將資源標記為已經(jīng)生產(chǎn) notify();//喚醒在等待操作資源的線程(隊列) } /** * 消費資源 */ public synchronized void destroy() { if (!flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "消費者****" + number); flag = false; notify(); } }
Producer.java
/**
* Created by yuandl on 2016-10-11.
*
/**
* 生產(chǎn)者
*/
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();
}
}
}
/**
* 消費者
*/
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();
}
}
}
/**
* 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();//生產(chǎn)者線程
new Thread(new Consumer(resource)).start();//消費者線程
}
}
Thread-0生產(chǎn)者------------1
Thread-1消費者****1
Thread-0生產(chǎn)者------------2
Thread-1消費者****2
Thread-0生產(chǎn)者------------3
Thread-1消費者****3
Thread-0生產(chǎn)者------------4
Thread-1消費者****4
Thread-0生產(chǎn)者------------5
Thread-1消費者****5
Thread-0生產(chǎn)者------------6
Thread-1消費者****6
Thread-0生產(chǎn)者------------7
Thread-1消費者****7
Thread-0生產(chǎn)者------------8
Thread-1消費者****8
Thread-0生產(chǎn)者------------9
Thread-1消費者****9
Thread-0生產(chǎn)者------------10
Thread-1消費者****10
Issues with multiple threads, multiple producers and multiple consumers
Demand scenario
Four threads, two of them are responsible for production, Two are responsible for consumption, the producer produces one and the consumer consumes one
Issues involved
NotifyAll() method: When the producer/consumer puts/takes out a product from the buffer, it issues a message to all other waiting threads The executable notification also gives up the lock and puts itself in a waiting state.
Test the 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();//生產(chǎn)者線程 new Thread(new Consumer(resource)).start();//生產(chǎn)者線程 new Thread(new Producer(resource)).start();//消費者線程 new Thread(new Producer(resource)).start();//消費者線程 } }
Running results
Thread-0生產(chǎn)者------------100
Thread-3消費者****100
Thread-0生產(chǎn)者------------101
Thread-3消費者****101
Thread-2消費者****101
Thread-1生產(chǎn)者------------102
Thread-3消費者****102
Thread-0生產(chǎn)者------------103
Thread-2消費者****103
Thread-1生產(chǎn)者------------104
Thread-3消費者****104
Thread-1生產(chǎn)者------------105
Thread-0生產(chǎn)者------------106
Thread-2消費者****106
Thread-1生產(chǎn)者------------107
Thread-3消費者****107
Thread-0生產(chǎn)者------------108
Thread-2消費者****108
Thread-0生產(chǎn)者------------109
Thread-2消費者****109
Thread-1生產(chǎn)者------------110
Thread-3消費者****110
101 was produced once and consumed twice
105 was produced but not consumed
Cause analysis
When two threads operate producer production or consumer consumption at the same time, if there is a producer or both threads wait(), notify() again, because one thread has changed the mark and the other thread has changed the mark again. This is caused by no judgment mark when executing directly.
If judgment mark, only once, will cause threads that should not run to run. A data error has occurred.
Solution
The while judgment mark solves the problem of whether the thread wants to run after it obtains execution rights! That is, every time wait() is followed by notify(), the mark must be judged again
Code improvement (if-> in Resource ;while)
Resource.java
/** * Created by yuandl on 2016-10-11./** * 資源 */ public class Resource { /*資源序號*/ private int number = 0; /*資源標記*/ private boolean flag = false; /** * 生產(chǎn)資源 */ public synchronized void create() { while (flag) {//先判斷標記是否已經(jīng)生產(chǎn)了,如果已經(jīng)生產(chǎn),等待消費; try { wait();//讓生產(chǎn)線程等待 } catch (InterruptedException e) { e.printStackTrace(); } } number++;//生產(chǎn)一個 System.out.println(Thread.currentThread().getName() + "生產(chǎn)者------------" + number); flag = true;//將資源標記為已經(jīng)生產(chǎn) notify();//喚醒在等待操作資源的線程(隊列) } /** * 消費資源 */ public synchronized void destroy() { while (!flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "消費者****" + number); flag = false; notify(); } }
Found the problem again
When printing to a certain value, such as 74 after production, the program runs stuck, as if it is locked.
Cause analysis
Notify: can only wake up one thread. If this party wakes up this party, it is meaningless. Moreover, the while judgment mark + notify will cause "deadlock".
Solution
NotifyAll solves the problem that the own thread will definitely wake up the other party's thread.
Final code improvement (notify()->notifyAll() in Resource)
Resource.java
/** * Created by yuandl on 2016-10-11./** * 資源 */ public class Resource { /*資源序號*/ private int number = 0; /*資源標記*/ private boolean flag = false; /** * 生產(chǎn)資源 */ public synchronized void create() { while (flag) {//先判斷標記是否已經(jīng)生產(chǎn)了,如果已經(jīng)生產(chǎn),等待消費; try { wait();//讓生產(chǎn)線程等待 } catch (InterruptedException e) { e.printStackTrace(); } } number++;//生產(chǎn)一個 System.out.println(Thread.currentThread().getName() + "生產(chǎn)者------------" + number); flag = true;//將資源標記為已經(jīng)生產(chǎn) notifyAll();//喚醒在等待操作資源的線程(隊列) } /** * 消費資源 */ public synchronized void destroy() { while (!flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "消費者****" + number); flag = false; notifyAll(); } }
Running results
Thread-0生產(chǎn)者------------412
Thread-2消費者****412
Thread-0生產(chǎn)者------------413
Thread-3消費者****413
Thread-1生產(chǎn)者------------414
Thread-2消費者****414
Thread-1生產(chǎn)者------------415
Thread-2消費者****415
Thread-0生產(chǎn)者------------416
Thread-3消費者****416
Thread-1生產(chǎn)者------------417
Thread-3消費者****417
Thread-0生產(chǎn)者------------418
Thread-2消費者****418
Thread-0生產(chǎn)者------------419
Thread-3消費者****419
Thread-1生產(chǎn)者------------420
Thread-2消費者****420

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Java and JavaScript are different programming languages, each suitable for different application scenarios. Java is used for large enterprise and mobile application development, while JavaScript is mainly used for web page development.

JavaScriptcommentsareessentialformaintaining,reading,andguidingcodeexecution.1)Single-linecommentsareusedforquickexplanations.2)Multi-linecommentsexplaincomplexlogicorprovidedetaileddocumentation.3)Inlinecommentsclarifyspecificpartsofcode.Bestpractic

The following points should be noted when processing dates and time in JavaScript: 1. There are many ways to create Date objects. It is recommended to use ISO format strings to ensure compatibility; 2. Get and set time information can be obtained and set methods, and note that the month starts from 0; 3. Manually formatting dates requires strings, and third-party libraries can also be used; 4. It is recommended to use libraries that support time zones, such as Luxon. Mastering these key points can effectively avoid common mistakes.

JavaScriptispreferredforwebdevelopment,whileJavaisbetterforlarge-scalebackendsystemsandAndroidapps.1)JavaScriptexcelsincreatinginteractivewebexperienceswithitsdynamicnatureandDOMmanipulation.2)Javaoffersstrongtypingandobject-orientedfeatures,idealfor

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScripthassevenfundamentaldatatypes:number,string,boolean,undefined,null,object,andsymbol.1)Numbersuseadouble-precisionformat,usefulforwidevaluerangesbutbecautiouswithfloating-pointarithmetic.2)Stringsareimmutable,useefficientconcatenationmethodsf

Event capture and bubble are two stages of event propagation in DOM. Capture is from the top layer to the target element, and bubble is from the target element to the top layer. 1. Event capture is implemented by setting the useCapture parameter of addEventListener to true; 2. Event bubble is the default behavior, useCapture is set to false or omitted; 3. Event propagation can be used to prevent event propagation; 4. Event bubbling supports event delegation to improve dynamic content processing efficiency; 5. Capture can be used to intercept events in advance, such as logging or error processing. Understanding these two phases helps to accurately control the timing and how JavaScript responds to user operations.

Java and JavaScript are different programming languages. 1.Java is a statically typed and compiled language, suitable for enterprise applications and large systems. 2. JavaScript is a dynamic type and interpreted language, mainly used for web interaction and front-end development.
