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 }

运行结果:

 

posted @ 2021-07-04 13:49  没有你哪有我  阅读(238)  评论(0编辑  收藏  举报