jdk提供的用于并发编程的同步器有哪些
同步器是一些使线程能够等待另一个线程的对象,允许它们协调动作。最常用的同步器是CountDownLatch和Semaphore,不常用的是Barrier 和Exchanger
CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作前需要一个或多个其他的线程处于阻塞状态时我们可以使用它,如田径比赛中,将每一名运动员看做一个工作线程,成绩记录员看做另一线程,显然成绩记录员开始记录员开始记录成绩前需要所有的运动员都先做好比赛准备并且同时开始起跑,我们需要就最后参赛者所的成绩得出一个排名,显然这个排名也必须得等所有的参赛者都完成了比赛后才能计算得到。这样的场景正好可以用CountDownLatch来实现。
/** *JAVA同步器之 CountDownLatch(不能循环使用,如果需要循环使用可以考虑使用CyclicBarrier) *两种比较常规用法: *1:new CountDownLatch(1);所有的线程在开始工作前需要做一些准备工作,当所有的线程都准备到位后再统一执行时有用 *2:new CountDownLatch(THREAD_COUNT);当所有的线程都执行完毕后,等待这些线程的其他线程才开始继续执行时有用 */
public class CountDownLatchTest { private static final int THREAD_COUNT=10; //在调用startSingal.countDown()之前调用了startSingal.await()的线程一律等待,直到startSingal.countDown()的调用 private static final CountDownLatch startSingal=new CountDownLatch(1); //在finishedSingal的初始化记数量通过调用finishedSingal.countDown()减少为0时调用了finishedSingal.await()的线程一直阻塞 private static final CountDownLatch finishedSingal=new CountDownLatch(THREAD_COUNT); public static void main(String[] args) throws InterruptedException { for(int i=0;i<THREAD_COUNT;i++){ new Thread("Task "+i){ public void run() { System.out.println(Thread.currentThread().getName()+" prepared!!"); try { startSingal.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //do something; System.out.println(Thread.currentThread().getName()+" finished!!"); finishedSingal.countDown(); }; }.start(); } Thread.sleep(1000); startSingal.countDown();//所有的线程被唤醒,同时开始工作 finishedSingal.await();//等待所有的线程完成!! System.out.println("All task are finished!!"); }
Barrier使用示例:
/** * JAVA同步器之Barrier(能够循环使用,当计数器增加到Barrier的初始化计数器之后马上会被置为0为下一次循环使用做准备) * Barrier能够为指定的一个或多个(一般为多个)线程设置一道屏障,只有当所有的线程都到达该屏障后才能一起冲过该屏障继续其他任务 一般可以new * CyclicBarrier(ThreadCount)来进行初始化,也可以new CyclicBarrier(ThreadCount,RunableAction)当初始化数量的线程都调用 * 了await()方法后触发RunableAction线程,也可以通过初始化一个new CyclicBarrier(ThreadCount+1)的Barrier在前置线程未执行完成时一直阻塞一个或多个 * 后续线程,这一点类似于CountDownLatch */
public class BarrierTest { private static final int THREAD_COUNT = 10; private static final CyclicBarrier barrier = new CyclicBarrier( THREAD_COUNT + 1, new Runnable() { @Override public void run() { System.out.println("All task are prepared or finished!!"); } }); public static void main(String[] args) throws InterruptedException, BrokenBarrierException { for (int i = 0; i < THREAD_COUNT; i++) { new Thread("Task " + i) { public void run() { try { System.out.println(Thread.currentThread().getName() + " prepared!!"); barrier.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } // do something System.out.println(Thread.currentThread().getName() + " finished!!"); }; }.start(); } barrier.await(); // --------------开始准备循环使用-------------- for (int i = 0; i < THREAD_COUNT; i++) { new Thread("Task " + i) { public void run() { // do something System.out.println(Thread.currentThread().getName() + " finished!!"); try { barrier.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } }; }.start(); } barrier.await(); }
Exchanger使用示例:
/** *JAVA同步器之Exchanger *Exchanger 可以实现工作的线程间完成安全的数据交换 */
public class ExchangerTest { final static Exchanger<List<String>> exchanger = new Exchanger<List<String>>(); public static void main(String[] args) { new Producer("Producer", exchanger).start(); new Consumer("Consumer", exchanger).start(); } static class Producer extends Thread { private Exchanger<List<String>> exchanger; /** * */ public Producer(String threadName, Exchanger<List<String>> exchanger) { super(threadName); this.exchanger = exchanger; } /* * (non-Javadoc) * * @see java.lang.Thread#run() */ @Override public void run() { List<String> products = new ArrayList<String>(); for (int i = 0; i < 10; i++) { products.add("product " + i); } try { List<String> results = exchanger.exchange(products); System.out.println("get results from consumer"); for (String s : results) { System.out.println(s); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } static class Consumer extends Thread { private Exchanger<List<String>> exchanger; /** * */ public Consumer(String threadName, Exchanger<List<String>> exchanger) { super(threadName); this.exchanger = exchanger; } /* * (non-Javadoc) * * @see java.lang.Thread#run() */ @Override public void run() { List<String> products = new ArrayList<String>(); for (int i = 0; i < 10; i++) { products.add("consumed " + i); } try { List<String> results = exchanger.exchange(products); System.out.println("got products from produces"); for (String s : results) { System.out.println(s); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
jdk提供的用于并发编程的同步器有哪些相关推荐
- java并发编程代码示例_java并发编程之同步器代码示例
java并发编程之同步器代码示例 发布时间:2020-09-08 16:53:41 来源:脚本之家 阅读:58 作者:Blessing_H 同步器是一些使线程能够等待另一个线程的对象,允许它们协调动作 ...
- java多线程 门闩_Java线程与并发编程实践----同步器(倒计时门闩,同步屏障)...
Java提供的synchronized关键字对临界区进行线程同步访问.由于基于synchronized很难 正确编写同步代码,并发工具类提供了高级的同步器.倒计时门闩(countdown latch) ...
- Java线程与并发编程实践----同步器(Phaser)
Phaser是一个更加弹性的同步屏障.和同步屏障一样,一个phaser使得一组线程在 屏障上等待,在最后一个线程到达之后,这些线程才得以继续执行.phaser也提供了和barrier action等价 ...
- java并发编程3:使用JDK并发包(java.util.concurrent)构建程序
原文地址为: java并发编程3:使用JDK并发包(java.util.concurrent)构建程序 java.util.concurrent 概述 JDK5.0 以后的版本都引入了高级并发特性,大 ...
- 《深入理解高并发编程:JDK核心技术》-冰河新书上市
大家好,我是冰河~~ 废话说多了没用,并发编程技术一直是初级程序员进阶高级工程师的前提条件,也是成为大厂程序员的必备技能,更是突破自身技术瓶颈的必经之路. 2022年6月我出版了"冰河技术丛 ...
- 学习笔记:Java 并发编程②_管程
若文章内容或图片失效,请留言反馈. 部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 视频链接:https://www.bilibili.com/video/av81461839 配套资料: ...
- Day623.并发编程工具类库使用错误问题 -Java业务开发常见错误
并发编程工具类库使用错误问题 多线程想必大家都知道,且JDK也为我们提供了很多并发编程的工具类库,接下来就是记录对应在业务开发中,可能会出现的并发编程工具类库使用错误的问题 一.线程复用导致信息错乱 ...
- Java 多线程与并发编程专题
Java 线程基础 Java 多线程开发 线程安全与同步 并发控制 非阻塞套接字(NIO) Java 5 中的并发 JDK 7 中的 Fork/Join 模式 相关书评 Java 平台提供了一套广泛而 ...
- java actor模型实例,详解Theron通过Actor模型解决C++并发编程的一种思维
现今,单台机器拥有多个独立的计算单元已经太常见了,这点在服务器的处理器上表现尤为明显,据AMD的一张2012-2013服务器路线图显示,服务器处理器的核心数将在2013年达到20颗之多,合理的利用CP ...
- 使用 Boost 的 IPC 和 MPI 库进行并发编程
使用非常流行的 Boost 库进行并发编程非常有意思.Boost 有几个用于并发编程领域的库:Interprocess (IPC) 库用于实现共享内存.内存映射的 I/O 和消息队列:Thread 库 ...
最新文章
- Error in Math.factor(x) : ‘abs’ not meaningful for factors
- 省钱小贴士(ECS):教你如何每年省出8w+ 块
- 买写真送手机系列 小米9王源限量版预售将在这些小米之家开启
- ib_logfile和mysql_bin_mysql的innodb中事务日志ib_logfile
- hdu 1166 树状数组解
- Openlayer:学习笔记之Source和Layer
- Cradle CFD—专业热流场分析工具
- 英文java简历模板下载_java软件工程师英文简历模板下载
- STM8L052低功耗模式
- 【程序设计入门-C语言】翁凯——初学者视角1
- PS打不开webp格式图片的解决方法
- [CSS基础]在一个网页中使用多种不同链接风格的CSS.
- 通俗讲解CDN是什么
- 期货基本面分析:,马来西亚10月1-10日棕榈油出口量较上月同期下降17.3%,但对中国出口创一年新高
- java基础:面向对象编程23-this课后练习boygirl
- Rabbitmq交换机详解
- HTML5树叶飘落动画
- 代理沙特SASO贸促会认证
- Linux常用命令——ssh命令
- 数据处理(10):SHP与JSON格式文件相互转换