JDk1.5提供了一個非常有用的包,Concurrent包,這個包主要用來操作一些並發操作,提供一些並發類,可以方便在項目當中傻瓜式應用。
JDK1.5以前,使用並發操作,都是通過Thread,Runnable來操作多線程;但是在JDK1.5之后,提供了非常方便的線程池(ThreadExecutorPool),主要代碼由大牛Doug Lea完成,其實是在jdk1.4時代,由於java語言內置對多線程編程的支持比較基礎和有限,所以他寫了這個,因為實在太過於優秀,所以被加入到jdk之中;
這次主要對CountDownLatch進行系統的講解
使用場景:比如對於馬拉松比賽,進行排名計算,參賽者的排名,肯定是跑完比賽之后,進行計算得出的,翻譯成Java識別的預發,就是N個線程執行操作,主線程等到N個子線程執行完畢之后,在繼續往下執行。
代碼示例
1 public static void testCountDownLatch(){ 2 3 int threadCount = 10; 4 5 final CountDownLatch latch = new CountDownLatch(threadCount); 6 7 for(int i=0; i< threadCount; i++){ 8 9 new Thread(new Runnable() { 10 11 @Override 12 public void run() { 13 14 System.out.println("線程" + Thread.currentThread().getId() + "開始出發"); 15 16 try { 17 Thread.sleep(1000); 18 } catch (InterruptedException e) { 19 e.printStackTrace(); 20 } 21 22 System.out.println("線程" + Thread.currentThread().getId() + "已到達終點"); 23 24 latch.countDown(); 25 } 26 }).start(); 27 } 28 29 try { 30 latch.await(); 31 } catch (InterruptedException e) { 32 e.printStackTrace(); 33 } 34 35 System.out.println("10個線程已經執行完畢!開始計算排名"); 36 }
執行結果:
線程10開始出發
線程13開始出發
線程12開始出發
線程11開始出發
線程14開始出發
線程15開始出發
線程16開始出發
線程17開始出發
線程18開始出發
線程19開始出發
線程14已到達終點
線程15已到達終點
線程13已到達終點
線程12已到達終點
線程10已到達終點
線程11已到達終點
線程16已到達終點
線程17已到達終點
線程18已到達終點
線程19已到達終點
10個線程已經執行完畢!開始計算排名
源碼分析:
1、CountDownLatch:A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
大致意思:也就是說主線程在等待所有其它的子線程完成后再往下執行
2、構造函數:CountDownLatch(int count)//初始化count數目的同步計數器,只有當同步計數器為0,主線程才會向下執行
主要方法:void await()//當前線程等待計數器為0
boolean await(long timeout, TimeUnit unit)//與上面的方法不同,它加了一個時間限制。
void countDown()//計數器減1
long getCount()//獲取計數器的值
3.它的內部有一個輔助的內部類:sync.
它的實現如下:
/**
* Synchronization control For CountDownLatch.
* Uses AQS state to represent count.
*/
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L;
Sync(int count) {
setState(count);
}
int getCount() {
return getState();
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
}
4.await()方法的實現
sync.acquireSharedInterruptibly(1);
-->if (tryAcquireShared(arg) < 0)//調用3中的tryAcquireShared()方法
doAcquireSharedInterruptibly(arg);//加入到等待隊列中
5.countDown()方法的實現
sync.releaseShared(1);
--> if (tryReleaseShared(arg))//調用3中的tryReleaseShared()方法
doReleaseShared();//解鎖
參考文章:
https://my.oschina.net/u/1185331/blog/502350
http://blog.itpub.net/30024515/viewspace-1432825/
