李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
CyclicBarrier和Semaphore简介
Leefs
2020-02-27 PM
1320℃
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
43
标签云
BurpSuite
Netty
Tomcat
排序
Hive
CentOS
Elastisearch
GET和POST
并发线程
散列
Kafka
二叉树
数据结构
FileBeat
数学
Git
MyBatisX
ajax
队列
Docker
Spark Streaming
Redis
高并发
Azkaban
Beego
Jenkins
Jquery
Scala
微服务
Java阻塞队列
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞