很多情况下 程序的主线程在做一项工作之前需要一系列的准备工作,只有这些准备工作都完成,主线程才能继续它的工作, CountDownLatch允许一个或多个线程等待另外N个线程完成某个操作之后才能执行这个类似Thread里的join()的功能。当某一个或多个线程start()以后, 用join()去等待。必须对应的线程执行完毕,join()后续的代码才能继续执行下去,CountDownLatch提供了join()的类似功能,并且能提供的更多! CountDownLatch提供了int参数(计数器)的构造方法,输入N就代表等待N个点完成。当我们调用countDown()方法时N就减1,直到N为0,await()后续代码才能继续执行 import java.util.concurrent.CountDownLatch; public class Test { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(2); new Thread(){ public void run() { try { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); Thread.sleep(3000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕"); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); new Thread(){ public void run() { try { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); Thread.sleep(3000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕"); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); try { System.out.println("等待2个子线程执行完毕..."); latch.await(); System.out.println("2个子线程已经执行完毕"); System.out.println("继续执行主线程"); } catch (InterruptedException e) { e.printStackTrace(); } } } ----------------------------------------------------------------------------------------------------------------------------------------- CyclicBarrier 允许两个或者多个线程在某个集合点同步。当一个线程到达集合点时,它将调用await()方法等待其它的线程。线程调用await()方法后, CyclicBarrier将阻塞这个线程并将它置入休眠状态等待其它线程的到来。等最后一个线程调用await()方法时,CyclicBarrier将唤醒所有等待的线程然后这些线程将继续执行。 CyclicBarrier可以传入另一个Runnable对象作为初始化参数。当所有的线程都到达集合点后,CyclicBarrier类将Runnable对象作为线程执行. 示例1. class TaskDemo implements Runnable{ private static Random rnd = new Random(); private String id; TaskDemo(String id){ this.id = id; } @Override public void run(){ try { Thread.sleep(rnd.nextInt(1000)); System.out.println("Thread " + id + " will wait"); TestCyclicBarrier.cb.await(); System.out.println("-------Thread " + id + " is over"); } catch (InterruptedException e) { } catch (BrokenBarrierException e) { } } } public class TestCyclicBarrier { public static CyclicBarrier cb = new CyclicBarrier(4); public static void main(String[] args){ ExecutorService es = Executors.newCachedThreadPool(); es.submit(new TaskDemo("a")); es.submit(new TaskDemo("b")); es.submit(new TaskDemo("c")); es.submit(new TaskDemo("d")); es.shutdown(); } } //输出结果如下: Thread b will wait Thread c will wait Thread d will wait Thread a will wait -------Thread b is over -------Thread c is over -------Thread a is over -------Thread d is over CyclicBarrier还提供一个更高级的构造函数CyclicBarrier(int parties, Runnable barrierAction),用于在线程到达屏障时,先执行barrierAction再释放其他线程锁 ,方便处理更复杂的业务场景。 代码如下: public class CyclicBarrierTest2 { //在线程到达屏障时,先执行A任务,待A任务返回后再释放其他线程的锁 static CyclicBarrier c = new CyclicBarrier(2, new A()); public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { try { c.await(); } catch (Exception e) { } System.out.println(1); } }).start(); new Thread(new Runnable() { @Override public void run() { try { c.await(); } catch (Exception e) { } System.out.println(2); } }).start(); } static class A implements Runnable { @Override public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(3); } } } //输出结果如下: 3 1 2 ----------------------------------------------------------------------------------------------------------------------------------------- Semaphore Semaphore可以用于做流量控制,特别公用资源有限的应用场景,比如数据库连接。 假如有一个需求,要读取几万个文件的数据,因为都是IO密集型任务,我们可以启动几十个线程并发的读取, 但是如果读到内存后,还需要存储到数据库中,而数据库的连接数只有10个, 这时我们必须控制只有十个线程同时获取数据库连接保存数据,否则会报错无法获取数据库连接。 这个时候,我们就可以使用Semaphore来做流控. Semaphore的用法也很简单,首先线程使用Semaphore的acquire()获取一个许可证,使用完之后调用release()归还许可证。 class SemaphoreTest { private static int threadCount = 100; static Semaphore semaphore = new Semaphore(10); static ExecutorService service = Executors.newFixedThreadPool(threadCount);// 创建大小为100的线程池 public static void main(String[] argus) { for (int i = 0; i < threadCount; i++) { final int c = i; service.execute(new Runnable() { @Override public void run() { try { semaphore.acquire();// 获取许可(绿灯) System.out.println("执行一些频繁的资源逻辑操作" + c); Thread.sleep(1000); semaphore.release();// 释放一个许可 } catch (InterruptedException e) { e.printStackTrace(); } } }); } service.shutdown(); } } ----------------------------------------------------------------------------------------------------------------------------------------- Exchanger Exchanger也很好理解,直译交换者,是用于2个线程之间交互数据的工具类,它提供了一个同步点, 其中一个线程先执行了exchange方法,会一直等待第二个线程执行到exchange方法,直到都达到了执行点,两个线程才交互数据 class TestExchanger { static Exchanger<Double> exchanger = new Exchanger<Double>();//定义交换者 static ExecutorService service = Executors.newFixedThreadPool(2);//2个大小的线程池 public static void main(String[] argus) { service.execute(new Runnable() { @Override public void run() { try { //例如录入银行流水计算一个总额 操作人A Double a = new Double(100); double exchangeB = exchanger.exchange(a); System.out.println("A自己的数据为:"+a+" 交换得到了" + exchangeB); } catch (InterruptedException e) { e.printStackTrace(); } } }); service.execute(new Runnable() { @Override public void run() { try { //例如录入银行流水计算一个总额 操作人B Double b = new Double(101); double exchangeB = exchanger.exchange(b); System.out.println("B自己的数据为:"+b+" 交换得到了:" + exchangeB); } catch (InterruptedException e) { e.printStackTrace(); } } }); service.shutdown(); } } //输出 A自己的数据为:100.0 交换得到了101.0 B自己的数据为:101.0 交换得到了:100.0
相关推荐
书籍是什么,是希望,是神圣的,你们这些译者简直就是在犯罪 ,不过要是英文功底不好,还是建议买本看吧,谁让你英文水平不如他们呢 《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序的...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在...
如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。 《Java并发编程...
《Java并发编程的艺术》内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,同时...
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 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在...
本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则...
本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则...
本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则...
《Java并发编程的艺术》内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,同时...
然后介绍了Thread类和Runnable接口,它们是Java并发API的重要组成部分。接着讨论了如何利用Java并发API的各种元素(从基本技巧到高级技巧),以及如何在强大的真实并发应用程序中实现它们。最后详细介绍了测试并发...
本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则...
本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则...
第37节并发工具类CountDownLatch详解00:22:04分钟 | 第38节并发工具类CyclicBarrier 详解00:11:52分钟 | 第39节并发工具类Semaphore详解00:17:27分钟 | 第40节并发工具类Exchanger详解00:13:47分钟 | 第41节...