java障礙器 CyclicBarrier

     Java5中,添加了障礙器類,爲了適應一種新的設計需求,好比一個大型的任務,經常須要分配好多子任務去執行,只有當全部子任務都執行完成時候,才能執行主任務,這時候,就能夠選擇障礙器了。
障礙器是多線程併發控制的一種手段

      一個同步輔助類,它容許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的線程的程序中,這些線程必須不時地互相等待,此時 CyclicBarrier 頗有用。由於該 barrier 在釋放等待線程後能夠重用,因此稱它爲循環 的 barrier。 

     CyclicBarrier 支持一個可選的 Runnable 命令,在一組線程中的最後一個線程到達以後(但在釋放全部線程以前),該命令只在每一個屏障點運行一次。若在繼續全部參與線程以前更新共享狀態,此屏障操做 頗有用。 
   CountDownLatch介紹:http://my.oschina.net/jielucky/blog/157946 java

  •  Java線程:新特徵-障礙器  -主線程   
package com.thread.cyclicBarrier;

/**
 * Java線程:新特徵-障礙器  -主線程
 * @author wangjie
 *
 */
public class MainTask implements Runnable {

	@Override
	public void run() {
		System.out.println("主線程執行了");
	}

}
  •  Java線程:新特徵-障礙器  -主線程
package com.lucky.concurrent.cyclicBarrier;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * Java線程:新特徵-障礙器 -子線程
 * 
 * @author wangjie
 * 
 */
public class ChildTask extends Thread {
	private CyclicBarrier cb;
	private static int index = 0;

	ChildTask(CyclicBarrier cb) {
		this.cb = cb;
	}

	@Override
	public void run() {
		try {
			if (index >= 2) {
				Thread.sleep(3000);
			}
			index++;
			System.out.println("子線程執行完畢,通知主線程");
			// 注:這裏parties裏的計數在運行時當調用CyclicBarrier:await()時,計數就加1,一直加到初始的值
			cb.await(); // 通知障礙器已經完成
			System.out.println("必定要等到主線程執行以後纔會執行   awati() 下面的 代碼");
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
	}
}

  • Java線程:新特徵-障礙器 <testClass>
package com.thread.cyclicBarrier;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** 
* Java線程:新特徵-障礙器 
* 
* @author wangjie 2013-08-26 17:03:10 
*/ 
public class TestCyclicBarrier {
	public void run() {
		// 建立障礙器,並設置MainTask爲全部定數量的線程都達到障礙點時候所要執行的任務(Runnable)
		CyclicBarrier cb = new CyclicBarrier(4, new MainTask());
		ExecutorService pool = Executors.newCachedThreadPool();
		pool.execute(new ChildTask(cb));
		pool.execute(new ChildTask(cb));
		pool.execute(new ChildTask(cb));
		pool.execute(new ChildTask(cb));
		pool.shutdown();
//		pool.shutdownNow();//有線程還沒執行完,不能當即中止。只能調用shutdown()
	}

	public static void main(String[] args) {
		new TestCyclicBarrier().run();
	}
}

執行結果能夠看出,全部子任務完成的時候,主任務執行了,達到了控制的目標。
注:這裏parties裏的計數在運行時當調用CyclicBarrier:await()時,計數就加1,一直加到初始的值。
如下比方是摘錄其餘文章:
多線程

CountDownLatch 是計數器, 線程完成一個就記一個, 就像 報數同樣, 只不過是遞減的. 併發

CyclicBarrier更像一個水閘, 線程執行就想水流, 在水閘處都會堵住, 等到水滿(線程到齊)了, 纔開始泄流. PS:這個形容很到位滴。
ide

相關文章
相關標籤/搜索