Java Learning Lesson 26th (Multithreading (vi))-Multi-producer multi-consumer issues

Source: Internet
Author: User
Tags finally block

Multi-producer and multi-consumer issues

To produce steamed bread consumption steamed bread as an example.


Class Resource {private String name;private int count = 1;private Boolean flag = false;public synchronized void set (String Name) {if (flag) {try {this.wait ()},} catch (Exception e) {//Todo:handle Exception}}this.name = name + count;count++; System.out.println (Thread.CurrentThread (). GetName () + "---producer----" +this.name); flag = True;notify ();} Public synchronized void out () {if (!flag) {try {this.wait ();} catch (Exception e) {//Todo:handle EXCEPTION}}SYSTEM.OUT.P Rintln (Thread.CurrentThread (). GetName () + "---------consumer--------" +this.name); flag = False;notify ();}} Class Producer implements Runnable{private Resource R; Producer (Resource r) {THIS.R = R;} public void Run () {while (true) {r.set ("steamed bun");}}} Class Consumer implements Runnable{private Resource R; Consumer (Resource r) {THIS.R = R;} public void Run () {while (true) {R.out ()}}} public class Main {public static void main (string[] args) {Resource r = new Resource (); Producer Pro = new Producer (r); Consumer con = new Consumer (r); Thread t0 = new Thread (PRO); Thread T1 = new Thread (PRO); Thread t2 = new Thread (con); thread t3 = new Thread (con); T0.start (); T1.start (); T2.start (); T3.start ();}}


The above code is prone to a problem, that is, the same steamed bread has been consumed several times, or some steamed bread has not been consumed. Single-born, single consumer does not have this problem

Cause: Notify wake-up thread is any one, such as T0 T1 are waiting state, T0 alive, T1 may also be awakened, so there will be a number of steamed bread without being consumed, in response to this problem, flag judgment can be changed to cycle, so it is easy to cause a deadlock situation: T0 T1 was wait, T2 normal consumption once, flag = False, Wake up T0, because the loop T2 T3 was wait, t0 execute once, flag = True, assuming wake T1, Judge T0 to Wait,while,t1 also entered the waiting, deadlock state

PS: The frozen state of the thread is awakened after this time do not participate in the judgment, down execution, so simply, a number of steamed bread is not produced by the consumption problem, is because the frozen state of the thread no longer continue to participate in the judgment caused, and the deadlock is caused by the cyclic judgment


Multi-production multi-consumption problem solving:

notify, instead of Notifyall, the current class of threads in a normal execution, wake all threads, the current same kind of thread because while, nature will continue to wait, the other side of any thread execution once, the other side remaining The thread continues to wait, thus enabling the generation of the corresponding consumption

Class Resource {private String name;private int count = 1;private Boolean flag = false;public synchronized void set (String Name) {while (flag) {try {this.wait ();} catch (Exception e) {//Todo:handle Exception}}this.name = name + count;count++;s Ystem.out.println (Thread.CurrentThread (). GetName () + "---producer----" +this.name); flag = True;notifyall ();} Public synchronized void out () {while (!flag) {try {this.wait ()} catch (Exception e) {//Todo:handle Exception}}system.ou T.println (Thread.CurrentThread (). GetName () + "---------consumer--------" +this.name); flag = False;notifyall ();}}

Summarize:

If judgment, will only be judged once, easy to cause the thread should not wake up, there is a problem

While determining whether to run after the thread gets the execution right

Notify, can only wake up any one thread, but wake the local thread, meaningless, and while+notify = deadlock

Notifyall, resolves that the thread of this party will surely wake the other thread

Therefore, multi-production and multi-consumption problem = while + Notifyall, but also caused inefficient problem (this party should not wake up, also wake up)


New features (JDK1.5 upgrade)

How do I not wake the party and wake the other one?

void Fu ()//early {synchronized (obj)//about the operation of the lock is implicit, only the lock itself knows {code ...}} Post-upgrade, the lock is encapsulated as Object lock L = new Reentrantlock (), the implicit way to manipulate the lock is defined in the object void Fu () {l.lock ();//Get Lock code: L.unlock ();//Release Lock}

Interface Lock

LockImplementations provide a wider synchronized range of locking operations than can be obtained using methods and statements. This implementation allows for a more flexible structure that can have very different properties and can support multiple related Condition objects.

ConditionThe Object monitor methods ( wait , notify and notifyAll ) are decomposed into distinct objects to Lock provide multiple wait sets (Wait-set) for each object by combining these objects with any implementation. This replaces the use of Lock synchronized methods and statements, Condition replacing the use of the Object monitor method.

Lock L = ...;      L.lock ();     try {         //access the resource protected by this lock     } finally {         l.unlock ();     }


Lock interface: Replaces the synchronous code block or the synchronization function, the implicit operation of the synchronous lock becomes a real operation, more flexible, can be a lock plus multiple monitors

Method:

L.lock ();//Get Lock

L.unlock ();//release lock, generally with the finally block of code

Condition interface: Implements the Wait (), notify (), Notifyall () methods in object, which are individually encapsulated by these monitor methods and become Condition monitor objects, which can be combined with arbitrary locks

Await () equals wait

Signal () equivalent to notify

Signalall (); Equivalent to Notifyall

Import Java.util.concurrent.locks.*;class Resource {private String name;private int count = 1;private Boolean flag = False ;//Create a lock L = new Reentrantlock ();//through an existing lock, get the Lock monitor object (Condition)//condition con = l.newcondition ();//through an existing lock, get two sets of monitors , a monitoring producer, a monitoring consumer condition Pro_con = l.newcondition (); Condition Consu_con = l.newcondition ();p ublic void Set (String name) {l.lock (); try {while (flag) {try {pro_con.await ();//Line Process Freeze}catch (Exception e) {//Todo:handle Exception}}this.name = name + count;count++; System.out.println (Thread.CurrentThread (). GetName () + "---producer 5.0----" +this.name); flag = True;//con.signalall ();// Wake all Threads consu_con.signal ();//Wake up the consumer thread without all} catch (Exception e) {//Todo:handle exception}finally{l.unlock ();//Release Lock}} public void Out () {l.lock (), try {while (!flag) {try {consu_con.await ()} catch (Exception e) {//Todo:handle Exception}}sy Stem.out.println (Thread.CurrentThread (). GetName () + "---------Consumer 5.0--------" +this.name); flag = false;// Con.signalall ();p ro_con.signal ();} catch (Exceptione) {//Todo:handle exception}finally{l.unlock ();}}} Class Producer implements Runnable{private Resource R; Producer (Resource r) {THIS.R = R;} public void Run () {while (true) {r.set ("steamed bun");}}} Class Consumer implements Runnable{private Resource R; Consumer (Resource r) {THIS.R = R;} public void Run () {while (true) {R.out ()}}} public class Main {public static void main (string[] args) {Resource r = new Resource (); Producer Pro = new Producer (r); Consumer con = new Consumer (r); Thread t0 = new Thread (PRO); thread T1 = new Thread (PRO); Thread t2 = new Thread (con); thread t3 = new Thread (con); T0.start (); T1.start (); T2.start (); T3.start ();}}

The actual development is such code

class   Boundedbuffer {//buffer final lock lock = new Reentrantlock ();    Final Condition notfull = Lock.newcondition ();    Final Condition notempty = Lock.newcondition ();   Final object[] items = new object[100];//Create a large container int putptr, takeptr, Count;     public void put (Object x) throws Interruptedexception {Lock.lock ();       try {while (count = = items.length) notfull.await ();        ITEMS[PUTPTR] = x;       if (++putptr = = items.length) putptr = 0;       ++count;     Notempty.signal ();     } finally {Lock.unlock ();     }} public Object take () throws Interruptedexception {Lock.lock ();       try {while (count = = 0) notempty.await ();        Object x = items[takeptr];       if (++takeptr = = items.length) takeptr = 0;       --count;       Notfull.signal ();     return x;     } finally {Lock.unlock (); }   }  }


Java Learning Lesson 26th (Multithreading (vi))-Multi-producer multi-consumer issues

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.