JUC中常用API详解
一、CountDownLatch
从以下版本开始:
1.5
适用场景:当我们需要等待其他所有业务都完成后,才能做一些业务操作的时候,可以用CountDownLatch来实现(类似倒计时)
常用方法:
1、构造器
2、countDown()
减少锁存器的计数,如果计数达到零,释放所有等待的线程。
3、await()
导致当前线程等到锁存器计数到零,除非线程是 interrupted 。
4、await(long timeout, TimeUnit unit)
使当前线程等待直到锁存器计数到零为止,除非线程为 interrupted或指定的等待时间过去。
5、getCount()
返回当前计数。
代码实现:
1 package com.lzp.juc; 2 3 import java.util.concurrent.CountDownLatch; 4 5 /** 6 * @Author LZP 7 * @Date 2021/7/3 22:54 8 * @Version 1.0 9 * 10 * 班上所有同学都离开教室之后,班长才能关门 11 */ 12 public class CountDownLatchTest { 13 14 public static void main(String[] args) throws InterruptedException { 15 CountDownLatch count = new CountDownLatch(6); 16 17 for (int i = 1; i <= 6; i++) { 18 new Thread(() -> { 19 System.out.println(Thread.currentThread().getName() + "\t" + "离开教室"); 20 count.countDown(); 21 }, String.valueOf(i)).start(); 22 } 23 24 count.await(); 25 26 System.out.println("班长关门****"); 27 } 28 29 }
运行结果:
二、CyclicBarrier
从以下版本开始:
1.5
适用场景:当我们在做一件事之前需要具备其他条件(类似 集齐七颗龙珠召唤神龙)时,我们才能去完成最终的任务
常用方法:
1、构造器
2、await()
等待所有 parties已经在这个障碍上调用了await。
3、await(long timeout, TimeUnit unit)
等待所有 parties 已经在此屏障上调用 await,或指定的等待时间过去。
4、reset()
将屏障重置为初始状态。
代码实现:
1 package com.lzp.juc; 2 3 import java.util.concurrent.BrokenBarrierException; 4 import java.util.concurrent.CyclicBarrier; 5 6 /** 7 * @Author LZP 8 * @Date 2021/7/3 22:57 9 * @Version 1.0 10 * 11 * 集齐七颗龙珠召唤 12 */ 13 public class CyclicBarrierTest { 14 15 public static void main(String[] args) { 16 CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> { 17 System.out.println("召唤神龙"); 18 }); 19 20 for (int i = 1; i <= 7; i++) { 21 final int tempInt = i; 22 new Thread(() -> { 23 System.out.println(Thread.currentThread().getName() + "\t" + "获得第" + tempInt + "颗龙珠"); 24 try { 25 cyclicBarrier.await(); 26 } catch (InterruptedException | BrokenBarrierException e) { 27 e.printStackTrace(); 28 } 29 }, String.valueOf(i)).start(); 30 } 31 } 32 33 }
运行结果:
三、Semaphore
从以下版本开始:
1.5
适用场景:多线程抢占多个资源(多人抢红包)
常用方法:
1、构造器
2、acquire()
从该信号量获取许可证,阻止直到可用,或线程为 interrupted 。
3、release()
释放许可证,将其返回到信号量。
代码实现(多位车主抢占多个停车位):
1 package com.lzp.juc; 2 3 import java.util.Random; 4 import java.util.concurrent.Semaphore; 5 import java.util.concurrent.TimeUnit; 6 7 /** 8 * @Author LZP 9 * @Date 2021/7/3 23:17 10 * @Version 1.0 11 * 12 * 多线程抢占多个资源(不再是以前的一个共享资源) 13 * 需求:7个车主抢占3个停车位 14 */ 15 public class SemaphoreTest { 16 17 public static void main(String[] args) { 18 int people = 7; 19 int carSeat = 3; 20 /* 21 Semaphore(int permits) 22 创建一个 Semaphore与给定数量的许可证和非公平公平设置。 23 */ 24 Semaphore semaphore = new Semaphore(carSeat); // 没有默认的无参构造 25 Random r = new Random(); 26 27 for (int i = 1; i <= people; i++) { 28 new Thread(() -> { 29 try { 30 // 开始抢 31 semaphore.acquire(); 32 // 抢到了 33 System.out.println(Thread.currentThread().getName() + "\t" + "抢到了停车位"); 34 // 模拟车位占用时间 35 TimeUnit.SECONDS.sleep(r.nextInt(3) + 1); 36 System.out.println(Thread.currentThread().getName() + "\t" + "离开了停车位"); 37 } catch (InterruptedException e) { 38 e.printStackTrace(); 39 } finally { 40 // 释放资源 41 semaphore.release(); 42 } 43 }, String.valueOf("车主" + i)).start(); 44 } 45 } 46 47 }
运行结果: