Analysis and solution of thread-safety problem caused by multi-producer and multi-consumer in Java Multithreading: Lock and condition

Source: Internet
Author: User
Multi-producer Multiple consumer//This is a sample class Resource {Private String name that generates error data;
    int count;

    Boolean flag = false;
            public synchronized void Produce (String name) {if (flag) {try {this.wait ();
            catch (Interruptedexception e) {e.printstacktrace ();
        } this.name = name + count;
        ++count;
        System.out.println (Thread.CurrentThread (). GetName () + "----" + Name+count + "---" + "produced");
        Flag = true;
    Notify ();
            Public synchronized void consume () {if (!flag) {try {this.wait ();
            catch (Interruptedexception e) {e.printstacktrace ();
        } System.out.println (Thread.CurrentThread (). GetName () + name +count+ "consumed");
        Flag = false;
    Notify ();

    } class Producer implements Runnable {Resource R; Public Producer (Resource r) {THIS.R = R;
    @Override public void Run () {while (true) {r.produce ("roast duck");

    }} class Consumer implements Runnable {Resource R;
    Public Consumer (Resource r) {THIS.R = R;
        @Override public void Run () {while (true) {r.consume (); 
        }} public class Producerconsumer {public static void main (string[] args) {Resource r=new Resource ();
        Producer producer=new Producer (R);
        Consumer consumer=new Consumer (R);
        Thread T0=new thread (producer);
        Thread T1=new thread (producer);
        Thread T2=new thread (producer);
        Thread t3=new thread (consumer);
        Thread t4=new thread (consumer);

        Thread t5=new thread (consumer);
        T0.start ();
        T1.start ();
        T2.start ();
        T3.start ();
        T4.start (); T5.start ();
1. Thread-safety issues are caused by:

When a production line begins to execute, there is another production line and a consumer thread that, at the end of the Run method, wakes up a process randomly and awakens another production line, causing the production line to still be able to produce solution 1 in the case of Flag=true : the flag if judgment is changed into a while loop, which solves the problem that the thread should be executed after the execution is acquired. To change the notify to Notifyall, if this side wakes up the thread of this side, it makes no sense, and while judgment +notify leads to deadlock.

but this method is expensive and can cause many useless judgments, reducing efficiency . Workaround 2: Use lock and Condition JDK1.5 later encapsulates synchronization and locks into objects, and turns an implicit method of manipulating the lock into an explicit action.

Examples of the use of an explicit lock lock  lock =new Reentrantlock ();

Lock.lock ();
Try () {
...
.. Code blocks that need to be synchronized ...
}
finally{
Lock.unlock ();
}
Condition Interface

The subclass object can be obtained by the lock method, and a lock can have multiple condition objects.
1. await ();
2. Signal ();
3. Signalall ();

Example
Lock lock=new reentrantlock ();
Condition cond=lock.newcondition ();
using lock and condition to solve multiple producer multiple consumer problems
Package multithread;
Import java.util.concurrent.locks.Condition;
Import Java.util.concurrent.locks.Lock;

Import Java.util.concurrent.locks.ReentrantLock;
 /** * Created by Lenovo on 2017/3/14.

    * * Class item{public int value;
    public Item (int value) {this.value = value;

    Class Buffer {Lock lock = new Reentrantlock ();
    Condition notfull = Lock.newcondition ();

    Condition notempty = Lock.newcondition ();
    Final int Max = 100;
    int putindex=0;
    int takeindex=0;
    int count = 0;

    Final item[] items = new Item[max];
        public void Produce () {lock.lock ();
                try {while (count = = Max) {try {notfull.await ();
                catch (Interruptedexception e) {e.printstacktrace ();
            } Item X=new item (PUTINDEX);
            Items[putindex] = x;
            System.out.println (x.value+ "has been produced"); If(++putindex = Max) Putindex = 0;
            ++count;
        Notempty.signal ();
        finally {Lock.unlock ();
        } public Item consume () {lock.lock ();
                try {while (count = = 0) {try {notempty.await ();
                catch (Interruptedexception e) {e.printstacktrace ();
            } Item x = Items[takeindex];
            System.out.println (x.value+ "has been consumed");
            if (++takeindex = = Max) Takeindex = 0;
            --count;
            Notfull.signal ();
        return x;
        finally {Lock.unlock ();

    }} class Producer implements Runnable {Buffer R;
    Public Producer (Buffer r) {THIS.R = R;
        @Override public void Run () {while (true) {r.produce (); }} class Consumer implements Runnable {Buffer R;
    Public Consumer (Buffer r) {THIS.R = R;
        @Override public void Run () {while (true) {r.consume ();
        }} public class Producerconsumer {public static void main (string[] args) {buffer r = new buffer ();
        Producer Producer = new Producer (r);
        Consumer Consumer = new Consumer (r);
        Thread t0 = new Thread (producer);
        thread T1 = new Thread (producer);
        Thread t2 = new Thread (producer);
        thread t3 = new thread (consumer);
        thread T4 = new Thread (consumer);

        Thread T5 = new Thread (consumer);
        T0.start ();
        T1.start ();
        T2.start ();
        T3.start ();
        T4.start ();
    T5.start ();
 }
}

* * Note points:
1. Lock.lock () and Lock.unlcok () surround the sync code block
2.lock.unlock () needs to be written in finally to ensure that even if an exception occurs in the synchronized code block, unlock () is still executed.
3. Just wake up a process in another monitor without Signalall (). **

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.