java多線程學習(四)—— ConcurrentHashMap和CountDownLatch的使用

ConcurrentHashMap

1、在jdk中,我們常用的map集合是 HashTableHashMap 這兩個,其中HashTable是線程安全的,即裏面的每一個方法都是線程同步的方法,使用了synchronized關鍵字修飾,而HashMap是線程不安全的。
2、雖然HashTable是線程安全的,但是效率很低,所以在jdk1.5之後,在併發包中就增加了一個線程安全,效率也高的map集合,叫 ConcurrentHashMap
3、ConcurrentHashMap 是接口ConcurrentMap的實現類,它還有一個實現類,是ConcurrentskipListMap (支持併發排序功能。彌補ConcurrentHas hMa p)
4、ConcurrentHashMap內部使用段(Segment)來表示這些不同的部分,每個段其實就是一個
小的HashTable,它們有自己的鎖。只要多個修改操作發生在不同的段上,它們就可以並
發進行。把一個整體分成了16個段(Segment.也就是最高支持16個線程的併發修改操作。
這也是在重線程場景時減小鎖的粒度從而降低鎖競爭的一種方案。並且代碼中大多共享變
量使用volatile關鍵字聲明,目的是第一時間獲取修改的內容,性能非常好。(這個也就是分段鎖)

CountDownLatch

CountDownLatch類位於java.util.concurrent包下,利用它可以實現類似計數器的功能。
比如有一個任務A,它要等待其他4個任務執行完畢之後才能執行,此時就可以利用CountDownLatch來實現這種功能了。

public class Test002 {

	public static void main(String[] args) throws InterruptedException {
		System.out.println("等待子線程執行完畢...");
		CountDownLatch countDownLatch = new CountDownLatch(2);
		new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println("子線程," + Thread.currentThread().getName() + "開始執行...");
				countDownLatch.countDown();// 每次減去1
				System.out.println("子線程," + Thread.currentThread().getName() + "結束執行...");
			}
		}).start();
		new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println("子線程," + Thread.currentThread().getName() + "開始執行...");
				//countDownLatch技術器減一
				countDownLatch.countDown();
				System.out.println("子線程," + Thread.currentThread().getName() + "結束執行...");
			}
		}).start();

		// 調用當前方法主線程阻塞  直到countDown結果爲0, 阻塞變爲運行狀態
		countDownLatch.await();
		System.out.println("兩個子線程執行完畢....");
		System.out.println("繼續主線程執行..");
	}
}

分析:上面的代碼中,定義了一個全局的countDownLatch技術器,讓主線程和兩個子線程都可以訪問這個countDownLatch技術器,每一個子線程運行完,countDownLatch技術器就減一,而主線程調用了countDownLatch.await()方法,一直處於阻塞狀態,知道兩個線程都運行完,countDownLatch技術器變成0,主線程才繼續執行
注意:上面的代碼中,如果countDownLatch技術器初始值爲 1 ,而有兩個線程,此時也不會報錯,只是在一個線程執行完成後,countDownLatch變成0,主線程就會和另一個子線程競爭cpu資源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章