Java高級技術第五章——高並發之CountDownLatch等同步器


前言

前言點擊此處查看:
http://blog.csdn.net/wang7807564/article/details/79113195

Wait&Notify

引出一個問題:

實現一個容器,提供兩個方法,add,size.
寫兩個線程,線程A添加10個元素到容器中,線程B實現監控元素的個數,當容器元素個數到5個時,線程B給出提示並結束。

這實際上是讓我們手動實現一個觀察者模式。
比較笨拙的實現方法是:使用volatile來修飾這個容器,然后在線程B中做一個while(true)的死循環來判斷容器中的size.
但是,這種做法太過於浪費CPU資源。

一種比較好的解決方法是使用wait&notify組合方法來實現。這兩個方法的實例化對象與synchronized作為鎖定對象的原理類似:可以實例化一個臨時對象,來調用這個對象的這兩個方法來實現同步,例如:

Object o = new object();
在N個線程中,分別實現:
Synchronized(o){代碼塊};

這里面調用對象o的方法,來實現這樣的同步。wait會釋放鎖,而notify不會釋放鎖。
但是,用這種方法來實現上述問題,需要監聽線程B先執行,執行過程中,需要兩個線程的notify和wait搭配使用。notify之后,A必須釋放鎖,B退出后,也必須notify,通知A繼續執行。這樣就可以做到兩個線程A和B交替執行。
這個線程通信過程比較繁瑣,在線程比較多的時候,一般都用notifyAll,很少有使用notify的。使用wait&notifyAll,常用來實現觀察者模式,實現的方法同上。
需要說明的是,在使用wait之前進行條件判斷的時候,不用if而用while,這是相當於多判斷一次,可以防止再次被搶占。
相關代碼網上有很多,沒有什么太多的內容,而且這種方法現在已經不怎么使用了,在此不列舉了。

CountDownLatch/CyclicBarrier/Semaphore

使用Latch(門閂)替代wait&notify來進行通知,好處是通信方式簡單,同時也可以指定等待的時間。使用await和countdown方法替代wait和notify。 CountDownLatch不涉及鎖定,當count的值為零時當前線程繼續運行。
當不涉及同步,只是涉及線程通信的時候,用synchronized + wait/notify就顯得太重了,
這時應該考慮countdownlatch/cyclicbarrier/semaphore這種同步器。
具體實現過程:

CountDownLatch latch = new CountDownLatch(1);

這里面實例化了一個CountDownLatch類,參數1代表每次只能被一個線程訪問,這個過程與P-V源語類似。
A業務線程:判斷條件不成立,latch.await();
B監聽線程:判斷條件成立,latch.countDown();


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com