国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

【Java并發編程實戰】-----“J.U.C”:Condition

2019-11-14 15:42:50
字體:
來源:轉載
供稿:網友

在看Condition之前,我們先來看下面這個例子:

工廠類,用來存放、取出商品:

public class Depot {    PRivate int depotSize;     //倉庫大小    private Lock lock;         //獨占鎖        public Depot(){        depotSize = 0;        lock = new ReentrantLock();    }        /**     * 商品入庫     * @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();        }    }        /**     * 商品出庫     * @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();        }    }}

生產者,生產商品,往倉庫里面添加商品:

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();    }}

消費者,消費商品,從倉庫里面取出商品:

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();    }}

測試類:

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(10);        customer.consume(5);        producer.produce(20);        producer.produce(5);        customer.consume(35);    }}

運行結果:

Thread-0 put 10 ----> the depotSize: 10Thread-1 get 5 ----> the depotSize: 5Thread-2 put 20 ----> the depotSize: 25Thread-3 put 5 ----> the depotSize: 30Thread-4 get 35 ----> the depotSize: -5

程序的運行結果是沒有錯誤的,先put10、然后get5、put20、put5、get35。程序運行結果非常正確,但是在現實生活中,這個實例存在兩處錯誤:

第一:倉庫的容量是有限的,我們不可能無限制的往倉庫里面添加商品。

第二:倉庫的容量是不可能為負數的,但是最后的結果為-5,與現實存在沖突。

針對于上面兩處錯誤,怎么解決?這就輪到Condition大顯神通了。

Condition

通過前面幾篇博客我們知道Lock提供了比synchronized更加強大、靈活的鎖機制,它從某種程度上來說替代了synchronized方式的使用。Condition從字面上面理解就是條件。對于線程而言它為線程提供了一個含義,以便在某種狀態(條件Condition)可能為true的另一個線程通知它之前,一直掛起該線程。

對于Condition,JDK API中是這樣解釋的:

Condition 將 Object 監視器方法(wait、notify 和 notifyAll)分解成截然不同的對象,以便通過將這些對象與任意 Lock 實現組合使用,為每個對象提供多個等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和語句的使用,Condition 替代了 Object 監視器方法的使用。

條件(也稱為條件隊列 或條件變量)為線程提供了一個含義,以便在某個狀態條件現在可能為 true 的另一個線程通知它之前,一直掛起該線程(即讓其“等待”)。因為訪問此共享狀態信息發生在不同的線程中,所以它必須受保護,因此要將某種形式的鎖與該條件相關聯。等待提供一個條件的主要屬性是:以原子方式 釋放相關的鎖,并掛起當前線程,就像 Object.wait 做的那樣。

Condition 實例實質上被綁定到一個鎖上。要為特定 Lock 實例獲得 Condition 實例,請使用其newCondition() 方法。下面我們通過Condition來解決上面的問題:這里只改倉庫Depot的代碼:

public class Depot {    private int depotSize;     //倉庫大小    private Lock lock;         //獨占鎖        private int capaity;       //倉庫容量        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();    }        /**     * 商品入庫     * @param value     */    public void put(int value){        lock.lock();        try {            int left = value;            while(left > 0){                //庫存已滿時,“生產者”等待“消費者”消費                while(depotSize >= capaity){                    fullCondition.await();                }                //獲取實際入庫數量:預計庫存(倉庫現有庫存 + 生產數量) > 倉庫容量   ? 倉庫容量 - 倉庫現有庫存     :    生產數量                //                  depotSize   left   capaity  capaity - depotSize     left                int inc = depotSize + left > capaity ? capaity - depotSize : left;                 depotSize += inc;                left -= inc;                System.out.println(Thread.currentThread().getName() + "----要入庫數量: " + value +";;實際入庫數量:" + inc + ";;倉庫貨物數量:" + depotSize + ";;沒有入庫數量:" + left);                            //通知消費者可以消費了                emptyCondition.signal();            }        } catch (InterruptedException e) {        } finally{            lock.unlock();        }    }        /**     * 商品出庫     * @param value     */    public void get(int value){        lock.lock();        try {            int left = value;            while(left > 0){                //倉庫已空,“消費者”等待“生產者”生產貨物                while(depotSize <= 0){                    emptyCondition.await();                }                //實際消費      倉庫庫存數量     < 要消費的數量     ?   倉庫庫存數量     : 要消費的數量                int dec = depotSize < left ? depotSize : left;                depotSize -= dec;                left -= dec;                System.out.println(Thread.currentThread().getName() + "----要消費的數量:" + value +";;實際消費的數量: " + dec + ";;倉庫現存數量:" + depotSize + ";;有多少件商品沒有消費:" + left);                            //通知生產者可以生產了                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(10);        customer.consume(5);        producer.produce(15);        customer.consume(10);        customer.consume(15);        producer.produce(10);    }}

運行結果:

Thread-0----要入庫數量: 10;;實際入庫數量:10;;倉庫貨物數量:10;;沒有入庫數量:0Thread-1----要消費的數量:5;;實際消費的數量: 5;;倉庫現存數量:5;;有多少件商品沒有消費:0Thread-4----要消費的數量:15;;實際消費的數量: 5;;倉庫現存數量:0;;有多少件商品沒有消費:10Thread-2----要入庫數量: 15;;實際入庫數量:15;;倉庫貨物數量:15;;沒有入庫數量:0Thread-4----要消費的數量:15;;實際消費的數量: 10;;倉庫現存數量:5;;有多少件商品沒有消費:0Thread-5----要入庫數量: 10;;實際入庫數量:10;;倉庫貨物數量:15;;沒有入庫數量:0Thread-3----要消費的數量:10;;實際消費的數量: 10;;倉庫現存數量:5;;有多少件商品沒有消費:0

在Condition中,用await()替換wait(),用signal()替換 notify(),用signalAll()替換notifyAll(),對于我們以前使用傳統的Object方法,Condition都能夠給予實現。


上一篇:Java工程轉C#

下一篇:JAVA小項目之搖獎機

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永宁县| 策勒县| 渑池县| 绵竹市| 石屏县| 澎湖县| 民乐县| 吴川市| 盈江县| 兖州市| 高密市| 原阳县| 乃东县| 武山县| 祁连县| 无为县| 怀仁县| 翁源县| 南丰县| 鄂托克旗| 高淳县| 双柏县| 方山县| 大埔县| 丹阳市| 洪江市| 会泽县| 冕宁县| 饶平县| 登封市| 洛隆县| 稷山县| 西宁市| 贵州省| 福鼎市| 安宁市| 临夏县| 天水市| 白河县| 谢通门县| 漳平市|