李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
CyclicBarrier和Semaphore简介
Leefs
2020-02-27 PM
1841℃
0条
# CyclicBarrier和Semaphore简介 ### 一、CyclicBarrier简介 CyclicBarrier的字面意思是可循环(Cyclic)使用的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法。 **需求** 一个线程组的线程需要等待所有线程完成任务后再继续执行下一次任务 ### 二、方法 **构造方法** ```java public CyclicBarrier(int parties) public CyclicBarrier(int parties, Runnable barrierAction) ``` > - parties 是参与线程的个数 > - 第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务 **重要方法** ```java public int await() throws InterruptedException, BrokenBarrierException public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException ``` > - 线程调用 await() 表示自己已经到达栅栏 > - BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时 **代码示例** 集齐七颗龙珠召唤神龙 ```java public class CyclicBarrierDemo { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{ System.out.println("***************召唤神龙"); }); for(int i=1;i<=7;i++){ final int tempInt = i; new Thread(()->{ System.out.println(Thread.currentThread().getName()+"\t 收集到:"+tempInt+"颗龙珠"); try { cyclicBarrier.await(); }catch (InterruptedException e){ e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } },String.valueOf(i)).start(); } } } ``` **运行结果** ``` 2 收集到:2颗龙珠 1 收集到:1颗龙珠 3 收集到:3颗龙珠 4 收集到:4颗龙珠 5 收集到:5颗龙珠 6 收集到:6颗龙珠 7 收集到:7颗龙珠 ***************召唤神龙 ``` ### 三、Semaphore简介 Semaphore也叫信号量,在JDK1.5被引入,用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。还可以用来实现某种资源池,或者对容器施加边界。 Semaphore内部维护了一组虚拟的许可,许可的数量可以通过构造函数的参数指定。 访问特定资源前,必须使用acquire方法获得许可,如果许可数量为0,该线程则一直阻塞,直到有可用许可。访问资源后,使用release释放许可。 Semaphore和ReentrantLock类似,获取许可有公平策略和非公平许可策略,默认情况下使用非公平策略。 当初始值为1时,可以用作互斥锁,并具备不可重入的加锁语义。 Semaphore将AQS的同步状态用于保存当前可用许可的数量。 **代码示例** 模拟6辆车抢三个车位 ```java public class SemaphoreDemo { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3);//模拟三个停车位 for(int i=1;i<=6;i++){ new Thread(()->{ try { semaphore.acquire(); System.out.println(Thread.currentThread().getName()+"\t 抢到车位"); try { TimeUnit.SECONDS.sleep(3); }catch (InterruptedException e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"\t 停车3秒后离开车位"); }catch (InterruptedException e){e.printStackTrace();}finally { semaphore.release(); } },String.valueOf(i)).start(); } } } ``` **运行结果** ``` 1 抢到车位 2 抢到车位 3 抢到车位 1 停车3秒后离开车位 3 停车3秒后离开车位 2 停车3秒后离开车位 5 抢到车位 4 抢到车位 6 抢到车位 6 停车3秒后离开车位 4 停车3秒后离开车位 5 停车3秒后离开车位 ```
标签:
并发编程
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/651.html
上一篇
countDownLatch简介
下一篇
【转载】Java阻塞队列--BlockingQueue
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
Java
Jquery
Java阻塞队列
Nacos
LeetCode刷题
Typora
nginx
锁
SpringCloudAlibaba
Linux
BurpSuite
栈
二叉树
持有对象
SQL练习题
序列化和反序列化
Yarn
SpringCloud
数据结构
Redis
MySQL
Spark SQL
JavaWEB项目搭建
MyBatisX
正则表达式
Spark Core
稀疏数组
Spark
Azkaban
微服务
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭