CountDownLatch、CyclicBarrier 的對比

CountDownLatch、CyclicBarrier 均可以用於: 在多線程異步執行過程當中,執行預約的流程後喚醒 指定的線程 進行相應的操做.
區別:
1,CountDownLatch 喚醒過一次,就廢棄了;CyclicBarrier能夠重複以前的預約流程,反覆喚醒。
2,CountDownLatch 可用於喚醒主線程,異步線程[任意線程,只要有他的實例];CyclicBarrier只能用於喚醒異步線程[貌似]。
3,CountDownLatch 喚醒指定線程後,當前線程並不阻塞;CyclicBarrier 喚醒指定線程後,當前線程會阻塞,等指定線程執行完成後,當前線程才繼續執行。
應用場景:
CountDownLatch:異步轉同步,,,
CyclicBarrier:批量多線程彙總,像短期跑批類的,
總結:
CyclicBarrier我是用的比較少,大部分場景都是用CountDownLatch就能夠了。java

package test;

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

/**
 * CountDownLatch、CyclicBarrier 均可以用於: 在多線程異步執行過程當中,執行預約的流程後喚醒 指定的線程 進行相應的操做.<br>
 *
 * 區別:<br>
 * 1,CountDownLatch 喚醒過一次,就廢棄了;CyclicBarrier能夠重複以前的預約流程,反覆喚醒。<br>
 * 2,CountDownLatch 可用於喚醒主線程,異步線程[任意線程,只要有他的實例];CyclicBarrier只能用於喚醒異步線程[貌似]。<br>
 * 3,CountDownLatch 喚醒指定線程後,當前線程並不阻塞;CyclicBarrier喚醒指定線程後,當前線程會阻塞,等指定線程執行完成後,當前線程才繼續執行。<br>
 * 
 * 應用場景:<br>
 * CountDownLatch:異步轉同步,,,<br>
 * CyclicBarrier:批量多線程彙總,像短期跑批類的,<br>
 * 
 * 總結:<br>
 * CyclicBarrier我是用的比較少,大部分場景都是用CountDownLatch就能夠了。
 * 
 * @author Yuanqy
 *
 */
public class TestLatch {

	@org.junit.Test
	public void test() throws InterruptedException {
		// ==CountDownLatch===================================
		try {
			final CountDownLatch latch = new CountDownLatch(5);
			long i = latch.getCount();
			for (int j = 0; j < i; j++) {
				new Thread() {
					@Override
					public void run() {
						System.out.println("CountDownLatch:" + latch.getCount() + "\t" + this.getName());//線程存在併發
						latch.countDown();// 計數遞減,當==0時 喚醒等待線程。
					}
				}.start();// 異步執行
			}
			latch.await();// 阻塞,直到latch.getCount()==0時喚醒
			System.out.println("===Main1 is finish===");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		// ==CyclicBarrier===================================
		final CyclicBarrier cb = new CyclicBarrier(5, new Thread() {
			@Override
			public void run() {
				System.out.println("===Last is finish===");//到達指定次數喚醒
			}
		});
		for (int i = 0; i < cb.getParties(); i++) {
			new Thread("Thread_" + i) {
				@Override
				public void run() {
					try {
						for (int x = 0; x < 2; x++) {// 我是能夠重複使用的哦。
							// cb.getNumberWaiting()返回已被await()的線程數量,不能用於計數。
							Thread.sleep(500);
							System.out.println("CyclicBarrier:" + cb.getNumberWaiting() + "\t" + this.getName());
							cb.await();// 阻塞當前線程, 喚醒CyclicBarrier 預約的線程先執行,當前線程等待
							System.out.println("Please watch me!\t" + this.getName());
						}
					} catch (InterruptedException | BrokenBarrierException e) {
						e.printStackTrace();
					}
				}
			}.start();// 異步執行
		}
		System.out.println("===Main2 is finish===");//這裏不阻塞
		Thread.currentThread().join();
	}
}

測試結果:多線程

CountDownLatch:5	Thread-0
CountDownLatch:5	Thread-1
CountDownLatch:3	Thread-2
CountDownLatch:2	Thread-3
CountDownLatch:1	Thread-4
===Main1 is finish===
===Main2 is finish===
CyclicBarrier:0	Thread_2
CyclicBarrier:0	Thread_0
CyclicBarrier:0	Thread_1
CyclicBarrier:3	Thread_3
CyclicBarrier:4	Thread_4
===Last is finish===
Please watch me!	Thread_4
Please watch me!	Thread_0
Please watch me!	Thread_1
Please watch me!	Thread_2
Please watch me!	Thread_3
CyclicBarrier:0	Thread_0
CyclicBarrier:0	Thread_1
CyclicBarrier:0	Thread_4
CyclicBarrier:3	Thread_2
CyclicBarrier:4	Thread_3
===Last is finish===
Please watch me!	Thread_3
Please watch me!	Thread_2
Please watch me!	Thread_4
Please watch me!	Thread_1
Please watch me!	Thread_0
相關文章
相關標籤/搜索