1.CountDownLatch
这个工具主要是将一个任务分解,等待所有的子任务完成才会做下面的操作,这个等待的操作主要是await控制的。计数值不能被重置,需要重置的情况需要使用CyclicBarrier。
下面的例子发现所有的线程都执行完成,才会打印done。
如果注释掉latch.await(); 发现done是在中间打印的,没有等待子任务都完成就执行了。
package concurrent; import java.util.concurrent.CountDownLatch; public class TestCountDownLatch { public static void main(String[] args) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(10); for(int i= 0; i<10;i++){ new Thread(new Runnable() { public void run() { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName() +"--> begin"); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--> end"); latch.countDown(); } },String.valueOf(i)).start(); } latch.await(); System.out.println("done------------"); } }
2.CyclicBarrier
这个工具主要是每个任务有多个阶段,如第三个阶段开始的前提必须是第二个阶段的所有人完成了任务。
可以向CyclicBarrier 其中注入runnable对象,这样计数器到达0时候自动触发该事件,同时计数值重置。
package concurrent; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class TestCyclicBarrier { private final static CyclicBarrier cyclicBarrier = new CyclicBarrier(10,new Runnable() { public void run() { System.out.println("新的任务开始啦"); } }); public static void main(String[] args) throws InterruptedException { for(int i= 0; i<10;i++){ new Thread(new Runnable() { public void run() { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName() +"--> begin run"); try { cyclicBarrier.await(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (BrokenBarrierException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println(Thread.currentThread().getName() +"--> begin jump"); try { cyclicBarrier.await(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (BrokenBarrierException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println(Thread.currentThread().getName() +"--> begin walk"); try { cyclicBarrier.await(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (BrokenBarrierException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--> end"); } },String.valueOf(i)).start(); } } }
执行结果
0--> begin run 3--> begin run 2--> begin run 1--> begin run 5--> begin run 4--> begin run 7--> begin run 6--> begin run 9--> begin run 8--> begin run 新的任务开始啦 8--> begin jump 3--> begin jump 1--> begin jump 4--> begin jump 0--> begin jump 9--> begin jump 6--> begin jump 7--> begin jump 5--> begin jump 2--> begin jump 新的任务开始啦 2--> begin walk 1--> begin walk 9--> begin walk 6--> begin walk 4--> begin walk 3--> begin walk 8--> begin walk 5--> begin walk 7--> begin walk 0--> begin walk 新的任务开始啦 7--> end 5--> end 3--> end 9--> end 6--> end 8--> end 4--> end 2--> end 1--> end 0--> end
3.Semaphor
计数器的价值在于控制只能有n个子任务访问某个资源。如下面的例子,只能同时存在三个进程。
package concurrent; import java.util.concurrent.Semaphore; public class TestSemaphor { static Semaphore semaphore = new Semaphore(3, true); public static void main(String[] args) { for(int i= 0; i<10;i++){ new Thread(new Runnable() { public void run() { // TODO Auto-generated method stub try { semaphore.acquire(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() +"--> begin "); try { Thread.currentThread().sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // System.out.println(Thread.currentThread().getName()+"--> end"); semaphore.release(); } },String.valueOf(i)).start(); } } }
相关推荐
│ 高并发编程第二阶段43讲、类加载的过程以及类主动使用的六种情况详细介绍.mp4 │ 高并发编程第二阶段44讲、被动引用和类加载过程的练习巩固训练题.mp4 │ 高并发编程第二阶段45讲、ClassLoader加载阶段发生的...
《Java并发编程的艺术》内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,同时...
在《JAVA并发编程实践》中,这 些便利工具的创造者不仅解释了它们究竟如何工作、如何使用,还阐释了创造它们的原因,及其背后的设计模式。JAVA并发编程实践英文版很不错,运用了n多知识。 本书作者都是Java ...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序...在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用,还阐释了创造它们的原因,及其背后的设计模式。
5.5 同步工具类 5.5.1 闭锁 5.5.2 FutureTask 5.5.3 信号量 5.5.4 栅栏 5.6 构建高效且可伸缩的结果缓存 第二部分 结构化并发应用程序 第6章 任务执行 6.1 在线程中执行任务 6.1.1 串行地执行任务 6.1.2 ...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序...在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用,还阐释了创造它们的原因,及其背后的设计模式。
如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。 《Java并发编程...
《Java并发编程实战》是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程...
本书全面介绍了如何使用Java 2平台进行并发编程,较上一版新增和扩展的内容包括:, ·存储模型 ·取消 ·可移植的并行编程 ·实现并发控制的工具类, Java平台提供了一套广泛而功能强大的api,工具和技术。...
在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用,还阐释了创造它们的原因,及其背后的设计模式。 编辑推荐 《JAVA并发编程实践》既能够成为读者的理论支持,又可以作为构建...
第8章介绍了Java中提供的并发工具类,这是并发编程中的瑞士军刀。 第9章介绍了Java中的线程池实现原理和使用建议。 第10章介绍了Executor框架的整体结构和成员组件。 第11章介绍几个并发编程的实战,以及排查并发...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序...在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用,还阐释了创造它们的原因,及其背后的设计模式。
一共包括了java内存模型、并发基础、锁、并发工具类、java并发编程实战、优化、阻塞队列、原子操作、并发集合、线程池、线程基础、自定义并发类等13个方面的内容。 学习并发编程一张图就搞定了。
, 《Java并发编程的艺术》内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序...在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用,还阐释了创造它们的原因,及其背后的设计模式。
java并发编程总结,包括多线程安全机制分析总结,Unsafe源码分析总结,并发工具类总结,ThreadLocal原理和使用,Fork/Join框架使用总结,同步容器和并发容器源码分析
5.5 同步工具类 5.5.1 闭锁 5.5.2 FutureTask 5.5.3 信号量 5.5.4 栅栏 5.6 构建高效且可伸缩的结果缓存 第二部分 结构化并发应用程序 第6章 任务执行 6.1 在线程中执行任务 6.1.1 串行地执行任务 6.1.2 ...
《Java并发编程实战》是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程...