多個線程同時開始啓動計時框架的設計與實現

在DEMO測試中,我有個需求描述如下:線程A、B、C、D,我需要他們同時開始運行,並記錄這四個線程全部完成所需要的時間。


這個藉助synchronizer可輕鬆完成。這裏我們使用CountDownLatch來實現,該方法的詳細描述參見我的上篇博文:點擊打開鏈接


核心代碼如下:demo請參見github

	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	private static long timer(Executor e,int concurrency,final Runnable action) throws InterruptedException{
		final CountDownLatch ready = new CountDownLatch(concurrency);
		final CountDownLatch start = new CountDownLatch(1);
		final CountDownLatch end = new CountDownLatch(concurrency);
		
		//將線程同時啓動並處於wait狀態,知道start.await因爲countDown=0被啓動
		for(int i=0;i<concurrency;i++){
			e.execute(new Runnable(){

				@Override
				public void run() {
					// TODO Auto-generated method stub
					ready.countDown();
					try {
						start.await();
						System.out.print(Thread.currentThread().getId()+"ready\n");
						action.run();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						Thread.currentThread().interrupt();
					}finally{
						System.out.print(Thread.currentThread().getId()+"end\n");
						end.countDown();
						
					}
				}
				
			});
		}
		ready.await();
		start.countDown();
		long startTime = System.nanoTime();
		end.await();
		return System.nanoTime()-startTime;

調用方法:
public static void main(String[] args) {
		// TODO Auto-generated method stub
		i = new AtomicInteger();
		ExecutorService e = Executors.newFixedThreadPool(5);
		Runnable action = new Runnable(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					//System.out.print(i.get()+"\n");
					TimeUnit.SECONDS.sleep(i.getAndAdd(5));
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			
		};
		try {
			long time = timer(e, 4, action);
			System.out.println(time);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		e.shutdown();

	}

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