几个好例子看懂CountDownLatch、CyclicBarrier、Semaphore

好的例子胜过语言描述注意观察测试结果,对于理解特别重要

CountDownLatch

  • 例子
/**
 * @CountDownLatch
 * 		阻塞某一个线程的对象,直到计数器为0
 * 		ps:实际操作CountDownLatch可以阻塞任意数量的线程,这里先忽略
 * 
 * @author it
 */
public class CountDownLatchDemo {
	
	/**
	 * 计数器初始化次数为5
	 */
	CountDownLatch countDownLatch = new CountDownLatch(5);
	
	public void start() throws InterruptedException {
		ExecutorService service = Executors.newCachedThreadPool();
		for (int i = 1; i <= 10; i++) {
			final int awaitTime = i;
			service.submit(() -> {
				try {
					TimeUnit.SECONDS.sleep(awaitTime);
					System.out.println(LocalTime.now().getSecond() + "秒 : " + Thread.currentThread().getName());
					// 计数器-1
					countDownLatch.countDown();
				} catch (Exception e) {
					e.printStackTrace();
				}
			});
		}
		// 计数器阻塞着,直到为0继续往后执行
		countDownLatch.await();
		System.out.println(LocalTime.now().getSecond() + "秒 : 计数器为0,阻塞终止 : " + Thread.currentThread().getName());

		service.shutdown();
	}

	public static void main(String[] args) throws InterruptedException {
		new CountDownLatchDemo().start();
	}

}
  • 测试结果
24秒 : pool-1-thread-1
25秒 : pool-1-thread-2
26秒 : pool-1-thread-3
27秒 : pool-1-thread-4
28秒 : pool-1-thread-5
28秒 : 计数器为0,阻塞终止 : main
29秒 : pool-1-thread-6
30秒 : pool-1-thread-7
31秒 : pool-1-thread-8
32秒 : pool-1-thread-9
33秒 : pool-1-thread-10

CyclicBarrier

基本例子
  • 例子一
/**
 * @CyclicBarrier
 * 		阻塞多个线程的对象,直到计数器为0,多个线程同时执行
 * 
 * @author it
 */
public class CyclicBarrierDemo {
	
	/**
	 * @parties
	 * 		计数器初始化次数为5
	 */
	CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
	
	public void start() throws InterruptedException {
		ExecutorService service = Executors.newCachedThreadPool();
		for (int i = 1; i <= 5; i++) {
			final int awaitTime = i;
			service.submit(() -> {
				try {
					TimeUnit.SECONDS.sleep(awaitTime);
					// 计数器-1,计数器阻塞着,直到为0继续往后执行
					cyclicBarrier.await();
					System.out.println(LocalTime.now().getSecond() + "秒 : " + Thread.currentThread().getName());
				} catch (Exception e) {
					e.printStackTrace();
				}
			});
		}
		System.out.println(LocalTime.now().getSecond() + "秒 : 主线程 : " + Thread.currentThread().getName());

		service.shutdown();
	}

	public static void main(String[] args) throws InterruptedException {
		new CyclicBarrierDemo().start();
	}

}
  • 测试结果
6秒 : 主线程 : main
11秒 : pool-1-thread-5
11秒 : pool-1-thread-4
11秒 : pool-1-thread-2
11秒 : pool-1-thread-3
11秒 : pool-1-thread-1
指定线程优先
  • 例子二
/**
 * @CyclicBarrier
 * 		阻塞多个线程的对象,直到计数器为0,多个阻塞线程同时执行
 * 
 * @author it
 */
public class CyclicBarrierDemo2 {
	
	/**
	 * @parties
	 * 		计数器初始化次数为5
	 * @barrierAction
	 *  	当计数器为0时,优先执行线程
	 */
	CyclicBarrier cyclicBarrier = new CyclicBarrier(5, ()->{
		try {
			System.out.println(LocalTime.now().getSecond() + "秒 : " + Thread.currentThread().getName());
			TimeUnit.SECONDS.sleep(1);
		} catch(Exception e) {}
	});
	
	public void start() throws InterruptedException {
		ExecutorService service = Executors.newCachedThreadPool();
		for (int i = 1; i <= 5; i++) {
			final int awaitTime = i;
			service.submit(() -> {
				try {
					TimeUnit.SECONDS.sleep(awaitTime);
					// 计数器-1,计数器阻塞着,直到为0继续往后执行
					cyclicBarrier.await();
					System.out.println(LocalTime.now().getSecond() + "秒 : " + Thread.currentThread().getName());
				} catch (Exception e) {
					e.printStackTrace();
				}
			});
		}
		System.out.println(LocalTime.now().getSecond() + "秒 : 主线程 : " + Thread.currentThread().getName());

		service.shutdown();
	}

	public static void main(String[] args) throws InterruptedException {
		new CyclicBarrierDemo2().start();
	}
	
}
  • 测试结果
    8秒有一个优先执行的线程
3秒 : 主线程 : main
8秒 : pool-1-thread-5
9秒 : pool-1-thread-5
9秒 : pool-1-thread-4
9秒 : pool-1-thread-1
9秒 : pool-1-thread-3
9秒 : pool-1-thread-2
指定线程优先
  • 例子三
/**
 * 循环使用CyclicBarrier
 * 
 * @CyclicBarrier
 * 		阻塞多个线程的对象,直到计数器为0,多个线程同时执行
 * 
 * @author it
 */
public class CyclicBarrierDemo3 {
	
	/**
	 * @parties
	 * 		计数器初始化次数为5
	 */
	CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
	
	public void start() throws InterruptedException {
		ExecutorService service = Executors.newCachedThreadPool();
		for (int i = 1; i <= 15; i++) {
			final int awaitTime = i;
			service.submit(() -> {
				try {
					TimeUnit.SECONDS.sleep(awaitTime);
					// 计数器-1,计数器阻塞着,直到为0继续往后执行
					int await = cyclicBarrier.await();
					if (await == 0) {
						cyclicBarrier.reset();
					}
					System.out.println(LocalTime.now().getSecond() + "秒 : " + Thread.currentThread().getName());
				} catch (Exception e) {
					e.printStackTrace();
				}
			});
		}
		System.out.println(LocalTime.now().getSecond() + "秒 : 主线程 : " + Thread.currentThread().getName());

		service.shutdown();
	}

	public static void main(String[] args) throws InterruptedException {
		new CyclicBarrierDemo3().start();
	}
}

  • 测试结果
53秒 : 主线程 : main
58秒 : pool-1-thread-5
58秒 : pool-1-thread-4
58秒 : pool-1-thread-3
58秒 : pool-1-thread-2
58秒 : pool-1-thread-1
3秒 : pool-1-thread-7
3秒 : pool-1-thread-9
3秒 : pool-1-thread-8
3秒 : pool-1-thread-6
3秒 : pool-1-thread-10
8秒 : pool-1-thread-15
8秒 : pool-1-thread-13
8秒 : pool-1-thread-12
8秒 : pool-1-thread-11
8秒 : pool-1-thread-14

Semaphore

  • 例子
/**
 * @Semaphore
 * 		资源控制的对象
 * 
 * @author it
 */
public class SemaphoreDemo {
	
	/**
	 * @permits - 在Semaphore管理下,只只允许同一个时间不超过两个线程(线程数量控制,即资源数据控制)
	 * @fair - 公平标志位,当为true时,等待越长的线程,优先级越高
	 */
	Semaphore semaphore = new Semaphore(2, true);
	
	public void start() {
		ExecutorService service = Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
			service.submit(() -> {
				try {
					// 拿一个资源
					semaphore.acquire();
					TimeUnit.SECONDS.sleep(1);
					System.out.println(LocalTime.now().getSecond() + "秒 : " + Thread.currentThread().getName());
					// 释放一个资源
					semaphore.release();
				} catch (Exception e) {
					e.printStackTrace();
				}
			});
		}
		service.shutdown();
	}
	
	public static void main(String[] args) {
		new SemaphoreDemo().start();
	}

}
  • 测试结果
15秒 : pool-1-thread-2
15秒 : pool-1-thread-1
16秒 : pool-1-thread-3
16秒 : pool-1-thread-4
17秒 : pool-1-thread-6
17秒 : pool-1-thread-5
18秒 : pool-1-thread-8
18秒 : pool-1-thread-7
19秒 : pool-1-thread-9
19秒 : pool-1-thread-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值