Java consumer producer model and JDK blocking queue Linkedblockingqueue implementation

Source: Internet
Author: User
Tags object object

Producer Consumer Issues

(English:Producer-consumer Problem), also known asLimited buffering issues(English:Bounded-buffer Problem), is aMulti-threaded synchronizationThe classic case of the problem. This issue describes two shared fixed sizeBufferThreads--The so-called "producer" and "consumer"--problems that can occur when actually running. The primary role of the producer is to generate a certain amount of data into the buffer, and then repeat the process. At the same time, consumers consume the data in buffers. The key to this issue is to ensure that producers do not add data when the buffer is full, and consumers do not consume data when the buffer is empty.

    To solve this problem, you must let the producer hibernate when the buffer is full (or simply discard the data), until the next time the consumer consumes the data in the buffer, the producer can be awakened, Begins adding data to the buffer. Similarly, you can let consumers hibernate when the buffer is empty, wait until the producer adds data to the buffer, and then wake the consumer. Typically, the interprocess communication method to solve this problem, commonly used methods are semaphore method [1] ET. If the workaround is not perfect, the deadlock

Applications in the real world

Like a restaurant, it has a chef and a waiter. The waiter must wait for the cook to prepare the food. When the chef is ready, he notifies the waiter, then the waiter will serve, then return to wait. This is an example of a task collaboration: The chef represents the producer and the waiter represents the consumer. Both tasks must be shaken when food is produced and consumed, and the system must be closed in an orderly manner.

Can be used to represent this relationship.


The realization of producer consumers

This is implemented by blocking queue linkedblockingqueue, blocking queues

Package Com.a.consumer;import java.util.concurrent.*;p ublic class Consumer3 {//Create a blocking queue private Linkedblockingqueu    e<object> queue = new linkedblockingqueue<object> (10);        Public Consumer3 () {} public void Start () {New Producer (). Start ();    New Consumer (). Start ();        public static void Main (string[] args) throws Exception {Consumer3 s3 = new Consumer3 ();    S3.start ();                    } class Producer extends Thread {public void run () {while (true) {try {                    Object o = new Object (); Take out an object Queue.put (o);                The queue will automatically block System.out.println when full ("Producer:" + O);                } catch (Interruptedexception e) {e.printstacktrace ();                }}}} class Consumer extends Thread {public void run () {while (true) {                   try {//Take out an object Object o = Queue.take ();                System.out.println ("Consumer:" + O);                } catch (Interruptedexception e) {e.printstacktrace (); }            }        }    }}
Below the studysource code of Linkedblockingqueue

First look at the Put method

Note the following sentence, it will call putlock.lockinterruptibly () This method, to try to get this Putlock this lock

    public void put (e e) throws interruptedexception {if (E = = null) throw new NullPointerException ();  Note:convention in all put/take/etc are to preset local var//holding count negative to indicate failure unless        Set.        int c =-1;        Final Reentrantlock putlock = This.putlock;        Final Atomicinteger count = This.count;          Putlock.lockinterruptibly (); try {/* * Note that count was used in wait guard even though it was * not protected by L Ock. This works because count can * is decrease at the this point (all other puts is shut * out by Lock) , and we (or some other waiting put) is * signalled if it ever changes from * capacity.             Similarly for all and uses of count in * other wait guards.            */while (count.get () = = capacity) {notfull.await ();            } enqueue (e); c = count.geTandincrement ();        if (c + 1 < capacity) notfull.signal ();        } finally {Putlock.unlock ();    } if (c = = 0) signalnotempty (); }

are looking atlockinterruptibly () method of the source code, is actually called the sync of this Synchronizer acquireinterruptibly this method

    public void lockinterruptibly () throws Interruptedexception {        sync.acquireinterruptibly (1);    }

Looking at acquireinterruptibly This method, is to check that the current thread interrupt identity bit is true, is true, will throw an interrupt exception, otherwise try to get the lock, when no lock is obtained, Will execute doacquireinterruptibly this method

    Public final void acquireinterruptibly (int arg) throws Interruptedexception {        if (thread.interrupted ())            throw New Interruptedexception ();        if (!tryacquire (ARG))            doacquireinterruptibly (ARG);    }
Here is a look at doacquireinterruptibly this method, pay attention to shouldparkafterfailedacquire this method, that is, when it is true, will then execute Parkandcheckinterrupt () This method, when it is also true, jumps out of the current loop, then cancels the acquisition lock and throws an exception at the same time.

    private void doacquireinterruptibly (int arg)        throws interruptedexception {        final node node = addwaiter ( node.exclusive);        try {for            (;;) {                final Node p = node.predecessor ();                if (p = = head && tryacquire (ARG)) {                    Sethead (node);                    P.next = null; Help GC                    return;                }                if (Shouldparkafterfailedacquire (p, node) &&                    parkandcheckinterrupt ()) break                    ;            }        } catch (RuntimeException ex) {            Cancelacquire (node);            Throw ex;        }        Arrive here only if interrupted        cancelacquire (node);        throw new Interruptedexception ();    }




Java consumer producer mode and JDK blocking queue Linkedblockingqueue implementation

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.