"Java Concurrency Programming Combat"-"J.U.C": Condition

Source: Internet
Author: User

Before looking at condition, let's take a look at the following example:

A factory class used for storing and removing goods:

public class Depot {    private int depotsize;     Warehouse size    private lock lock;         Exclusive lock public        Depot () {        depotsize = 0;        lock = new Reentrantlock ();    }        /**     * Commodity Storage     * @param value     *    /public void put (int value) {        try {            lock.lock ();            Depotsize + = value;            System.out.println (Thread.CurrentThread (). GetName () + "put" + value + "----> The Depotsize:" + depotsize);        } finally{            Lock.unlock ();        }    }        /**     * Commodity out of stock     * @param value *     /public    void get (int value) {        try {            lock.lock ();            Depotsize-= value;            System.out.println (Thread.CurrentThread (). GetName () + "get" + value + "----> The Depotsize:" + depotsize);        } finally{            Lock.unlock ();}}}    

Producers, produce goods, add goods to the warehouse:

public class Producer {    private Depot Depot;        Public Producer (Depot Depot) {        this.depot = Depot;    }        public void produce (final int value) {        new Thread () {public            void run () {                depot.put (value);            }        }. Start ();    }}

Consumers, consumer goods, from the warehouse to take out goods:

public class Customer {    private Depot Depot;        Public Customer (Depot Depot) {        this.depot = Depot;    }        public void consume (final int value) {        new Thread () {public            void run () {                depot.get (value);            }        }. Start ();    }}

Test class:

public class Test {public    static void Main (string[] args) {        Depot Depot = new Depot ();                Producer Producer = new Producer (depot);        Customer customer = new Customer (depot);                Producer.produce (ten);        Customer.consume (5);        Producer.produce (a);        Producer.produce (5);        Customer.consume (+);    }}

Operation Result:

Thread-0 put----> The depotsize:10thread-1 get 5----> The depotsize:5thread-2 put----> The depotsize: 25thread-3 put 5----> the depotsize:30thread-4 get----> The depotsize:-5

The running result of the program is no error, first put10, then Get5, put20, Put5, Get35. The program runs very correctly, but in real life there are two errors in this instance:

First: The capacity of the warehouse is limited, we can not unlimited to add goods to the warehouse.

Second: The capacity of the warehouse is not likely to be negative, but the final result is-5, conflict with the reality.

For the above two errors, how to solve? This is the turn of condition prowess.

Condition

We know from the previous blogs that lock provides a more powerful and flexible locking mechanism than synchronized, which in some way replaces the use of synchronized. Condition is literally the condition. For a thread it provides a meaning for the thread to suspend the thread until it is notified by another thread of a state (condition condition) that may be true.

This is explained in the CONDITION,JDK API:

Condition the object Monitor method (wait, notify, and Notifyall) into distinct objects to provide multiple wait set (Wait-set) for each object by combining these objects with any Lock implementation. Where Lock replaces the use of the Synchronized method and the statement, Condition replaces the use of the Object monitor method.

A condition (also known as a conditional queue or condition variable) provides a means for a thread to suspend the thread (that is, let it "wait") until another thread that a state condition might now be true notifies it. Because access to this shared state information occurs in different threads, it must be protected so that a form of lock is associated with that condition. The primary property for waiting to provide a condition is to atomically release the associated lock and suspend the current thread, as Object.wait did.

condition instance is essentially bound to a lock. To obtain an Condition instance for a particular Lock instance, use its newcondition () method. Below we solve the above problem through condition: This only changes the warehouse depot code:

public class Depot {private int depotsize;         Warehouse size private lock lock;       Exclusive lock private int capaity;            Warehouse capacity private Condition fullcondition;        Private Condition emptycondition;        Public Depot () {this.depotsize = 0;        This.lock = new Reentrantlock ();        this.capaity = 15;        This.fullcondition = Lock.newcondition ();    This.emptycondition = Lock.newcondition ();        }/** * Commodity storage * @param value */public void put (int value) {lock.lock ();            try {int left = value;                    while (Left > 0) {//Inventory is full, "producer" Waits for "consumer" consumption while (Depotsize >= capaity) {                Fullcondition.await (); }//Get the actual inbound quantity: Expected inventory (warehouse on-hand inventory + production quantity) > warehouse capacity?                Warehouse Capacity-Warehouse on-hand inventory: Production quantity//Depotsize left capaity Capaity-depotsize left int inc = Depotsize + Left > capaity? Capaity -Depotsize:left;                Depotsize + = Inc;                Left-to-= Inc; System.out.println (Thread.CurrentThread (). GetName () + "----to storage Quantity:" + value + ";; Actual number of storage: "+ inc +";; Warehouse Cargo Quantity: "+ Depotsize +";;                            No storage quantity: "+ Left";            Inform consumers to consume the emptycondition.signal ();        }} catch (Interruptedexception e) {} finally{lock.unlock ();        }}/** * Commodity out of stock * @param value */public void get (int value) {lock.lock ();            try {int left = value; while (Left > 0) {//Warehouse is empty, "consumer" waits for "producer" to produce goods while (depotsize <= 0) {emp                Tycondition.await ();   }//Actual consumption warehouse inventory quantity < Quantity to be consumed? Warehouse Inventory Quantity: Amount to be consumed int dec = Depotsize < left?                Depotsize:left;                depotsize = Dec;                Left-= Dec; System.out.println (Thread.currenttHread (). GetName () + "----Quantity to consume:" + value + ";; Amount of actual consumption: "+ Dec +";; Warehouse Extant Quantity: "+ Depotsize +";;                            How many items are not consumed: "+ Left";            Inform the producer to produce the Fullcondition.signal ();        }} catch (Interruptedexception e) {e.printstacktrace ();        } finally{Lock.unlock (); }    }}

Test

public class Test {public    static void Main (string[] args) {        Depot Depot = new Depot ();                Producer Producer = new Producer (depot);        Customer customer = new Customer (depot);                Producer.produce (ten);        Customer.consume (5);        Producer.produce (a);        Customer.consume (ten);        Customer.consume (a);        Producer.produce (ten);    }}

Operation Result:

Thread-0----to the number of storage: 10;; Number of physical storage: 10;; Warehouse Cargo Quantity: 10;; No storage quantity: 0thread-1----Quantity to consume: 5;; Number of actual consumption: 5;; Number of warehouses remaining: 5;; How many items have not been consumed: 0thread-4----Quantity to consume: 15;; Number of actual consumption: 5;; Number of warehouses remaining: 0;; How many items have not been consumed: 10thread-2----to the number of storage: 15;; Number of physical storage: 15;; Warehouse Cargo Quantity: 15;; No storage quantity: 0thread-4----Quantity to consume: 15;; Number of actual consumption: 10;; Number of warehouses remaining: 5;; How many items have not been consumed: 0thread-5----to the number of storage: 10;; Number of physical storage: 10;; Warehouse Cargo Quantity: 15;; No storage quantity: 0thread-3----Quantity to consume: 10;; Number of actual consumption: 10;; Number of warehouses remaining: 5;; How many items have not been consumed: 0

In condition, replace wait () with await (), replace notify () with signal (), replace Notifyall () with Signalall (), and for our previous use of the traditional object method, Condition are able to give fulfillment.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

"Java Concurrency Programming Combat"-"J.U.C": Condition

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.