JUC包下的CountDownLatch,CyclicBarrier,Semaphore

时间:2022-04-29
本文章向大家介绍JUC包下的CountDownLatch,CyclicBarrier,Semaphore,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

①.从CountDownLatch的设计来看,可以做汇总的操作,例如计算员工工资,这边启动多个线程同时计算等所有线程执行完毕之后,计算需要发放的总额

final ConcurrentHashMap<String, Integer> resultMap = new ConcurrentHashMap<String, Integer>();
		final CountDownLatch c = new CountDownLatch(10);
		final Random r = new Random();
		for (int i = 0; i < 10; i++) {
			
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						
						String sub =Thread.currentThread().getName().substring(Thread.currentThread().getName().indexOf("-")+1);
						System.out.println("threadName:" + Thread.currentThread().getName());
						if(Integer.parseInt(sub) %2 == 0){
							System.out.println(Thread.currentThread().getName()+" wait 2s");
							Thread.sleep(2000);
						}else{
							System.out.println(Thread.currentThread().getName()+" wait 0.5s");
							Thread.sleep(500);
							
						}
						resultMap.put(Thread.currentThread().getName(), r.nextInt(10000));
						c.countDown();
					} catch (Exception e) {
						e.printStackTrace();
					}

				}
			}).start();
		}
		

		c.await();
		System.out.println("n***********************n");
		int sum = 0;
		for(String key :resultMap.keySet()){
			Integer num = resultMap.get(key);
			sum += num;
			System.out.println(num);
			
		}
		System.out.println("end:"+sum);
控制台:
threadName:Thread-2
threadName:Thread-4
Thread-2 wait 2s
threadName:Thread-3
Thread-3 wait 0.5s
threadName:Thread-6
Thread-6 wait 2s
threadName:Thread-1
Thread-1 wait 0.5s
threadName:Thread-0
Thread-0 wait 2s
Thread-4 wait 2s
threadName:Thread-8
Thread-8 wait 2s
threadName:Thread-7
Thread-7 wait 0.5s
threadName:Thread-5
Thread-5 wait 0.5s
threadName:Thread-9
Thread-9 wait 0.5s

***********************

8881
7993
3441
8408
100
1074
6542
4448
4216
2839
end:47942

②.CyclicBarrier可以用来做初始化操作之后,所有的线程统一执行:

System.out.println("init finish.");
		System.out.println("************************");
		final CyclicBarrier cb = new CyclicBarrier(10);
		for (int i = 0; i < 10; i++) {
			new Thread(new Runnable() {

				@Override
				public void run() {
					try {
						System.out.println("ThreadName:" + Thread.currentThread().getName());
						Thread.sleep(3000);
						cb.await();
						System.out.println("ThreadName:" + Thread.currentThread().getName()
						        + ",end!");
					} catch (InterruptedException | BrokenBarrierException e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
控制台:
init finish.
************************
ThreadName:Thread-0
ThreadName:Thread-1
ThreadName:Thread-2
ThreadName:Thread-3
ThreadName:Thread-4
ThreadName:Thread-5
ThreadName:Thread-6
ThreadName:Thread-7
ThreadName:Thread-8
ThreadName:Thread-9
ThreadName:Thread-7,end!
ThreadName:Thread-1,end!
ThreadName:Thread-2,end!
ThreadName:Thread-8,end!
ThreadName:Thread-9,end!
ThreadName:Thread-4,end!
ThreadName:Thread-3,end!
ThreadName:Thread-0,end!
ThreadName:Thread-6,end!
ThreadName:Thread-5,end!

③.Semaphore(信号量)

    //构造方法permits表示一次性接受几个线程通过,比如有20个线程,permits=5,那么则表示一次性可以有五个线程通过,若为1那么作用相当于是一把锁,

   new Semaphore(permits);

acquire相当于是用来获取一个令牌,每获取一个令牌则减少一个,当所有令牌用完之后,剩余线程进入等待,直到有其他线程执行完毕并且归还令牌,剩余线程准备抢夺令牌以便执行,

	ExecutorService exec = Executors.newCachedThreadPool();

		// 只能5个线程同时访问

		final Semaphore semp = new Semaphore(5);
		for (int i = 0; i < 20; i++) {

			final int NO = i;

			Runnable run = new Runnable() {

				public void run() {

					try {
						// 获取许可
						semp.acquire();
						System.out.println("No: " + (NO+1));
						Thread.sleep(2000);
						// 访问完后,释放
						semp.release();
						System.out.println("------------");
						System.out.println("availability:" + semp.availablePermits());
						Thread.sleep(1000);

					} catch (InterruptedException e) {

						e.printStackTrace();

					}

				}

			};

			exec.execute(run);

		}

		// 退出线程池

		exec.shutdown();

从控制台可以看出,第一次5个线程一起执行,后面线程的执行受上一次线程执行并且释放令牌时间的影响 ,等所有线程执行完毕则显示共有五个令牌可以使用

No: 1
No: 2
No: 4
No: 3
No: 5
------------
No: 8
No: 6
------------
availability:0
------------
availability:0
------------
------------
availability:0
availability:0
availability:0
No: 10
No: 7
No: 9
No: 12
------------
availability:0
------------
No: 11
No: 13
------------
------------
availability:0
------------
availability:0
No: 15
availability:0
No: 14
availability:1
------------
No: 16
availability:0
------------
No: 18
No: 17
------------
availability:0
------------
availability:0
availability:0
No: 19
------------
No: 20
availability:0
------------
availability:1
------------
------------
availability:3
availability:3
------------
availability:4
------------
availability:5