博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并发工具类的使用 CountDownLatch,CyclicBarrier,Semaphore,Exchanger
阅读量:5839 次
发布时间:2019-06-18

本文共 4538 字,大约阅读时间需要 15 分钟。

1.CountDownLatch

 允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。

 A CountDownLatch用给定的计数初始化。 await方法阻塞,直到由于countDown()方法的调用而导致当前计数达到零,之后所有等待线程被释放,并且任何后续的await 调用立即返回。 这是一个一次性的现象 - 计数无法重置。 如果您需要重置计数的版本,请考虑使用 。

public class CountDownLatchTest {    public void meeting (CountDownLatch countDownLatch) {        System.out.println(Thread.currentThread().getName() + "到达会议室,等待开会。。。");        try {            countDownLatch.countDown();        } catch (Exception e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        //CountDownLatch 传入线程数,当传入的线程数全部执行完成后再往后执行,否则一直等待        CountDownLatch countDownLatch = new CountDownLatch(3);        CountDownLatchTest countDownLatchTest = new CountDownLatchTest();        Runnable runnable = () -> countDownLatchTest.meeting(countDownLatch);        new Thread(runnable).start();        new Thread(runnable).start();        new Thread(runnable).start();        try {            countDownLatch.await();        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("全部线程执行完毕");    }}

 

2.CyclicBarrier

 允许一组线程全部等待彼此达到共同屏障点的同步辅助。 循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。 屏障被称为循环 ,因为它可以在等待的线程被释放之后重新使用。

A CyclicBarrier支持一个可选的命令,每个屏障点运行一次,在派对中的最后一个线程到达之后,但在任何线程释放之前。 在任何一方继续进行之前,此屏障操作对更新共享状态很有用。

public class CyclicBarrierTest {    public void meeting (CyclicBarrier cyclicBarrier) {        System.out.println(Thread.currentThread().getName() + "到达会议室,等待开会。。。");        try {            cyclicBarrier.await();            System.out.println(Thread.currentThread().getName() + "发言中。。。");        } catch (Exception e) {            e.printStackTrace();        }    }        public static void main(String[] args) {        //CyclicBarrier构造方法一,传入线程数,当传入的线程数全部执行完成后再往后执行,否则一直等待        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);        //CyclicBarrier构造方法二,传入线程数,当传入的线程数全部执行完成后再往后执行,否则一直等待;传入最后一个线程执行完成后将执行的代码 从写runnable接口        CyclicBarrier cyclicBarrier1 = new CyclicBarrier(3, () -> System.out.println(Thread.currentThread().getName() + "已经全部到达,开始开会"));        CyclicBarrierTest cyclicBarrierTest = new CyclicBarrierTest();        Runnable runnable = () -> cyclicBarrierTest.meeting(cyclicBarrier1);        new Thread(runnable).start();        new Thread(runnable).start();        new Thread(runnable).start();    }}

 

3.Semaphore

 一个计数信号量。 在概念上,信号量维持一组许可证。 如果有必要,每个acquire()都会阻塞,直到许可证可用,然后才能使用它。 每个release()添加许可证,潜在地释放阻塞获取方。 但是,没有使用实际的许可证对象; Semaphore只保留可用数量的计数,并相应地执行

 信号量通常用于限制线程数,而不是访问某些(物理或逻辑)资源。

 

public class SemaphoreTest {    public void method(Semaphore semaphore) {        try {            semaphore.acquire();            System.out.println(Thread.currentThread().getName()+" is run ...");            Thread.sleep(2000);            semaphore.release();        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        SemaphoreTest semaphoreTest = new SemaphoreTest();        Semaphore semaphore = new Semaphore(10);        while (true) {            new Thread(() -> semaphoreTest.method(semaphore)).start();        }    }}

 

4.Exchanger

线程可以在成对内配对和交换元素的同步点。 每个线程在输入exchange方法时提供一些对象,与合作者线程匹配,并在返回时接收其合作伙伴的对象。 交换器可以被视为一个的双向形式 。 交换器在诸如遗传算法和管道设计的应用中可能是有用的。

public class ExchangerTest {        public void a(Exchanger
exchanger) { System.out.println("a 方法开始执行。。。"); try { System.out.println("a 方法开始抓取数据..."); Thread.sleep(4000); System.out.println("a 方法抓取数据结束"); String res = "12345"; System.out.println("a 等待对比结果"); exchanger.exchange(res); } catch (InterruptedException e) { e.printStackTrace(); } } public void b(Exchanger
exchanger) { System.out.println("b 方法开始执行。。。"); try { System.out.println("b 方法开始抓取数据。。。"); Thread.sleep(4000); System.out.println("b 方法抓取数据结束"); String res = "12345"; String value = exchanger.exchange(res); System.out.println("比对结果为:" + value.equals(res)); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { ExchangerTest exchangerTest = new ExchangerTest(); Exchanger
exchanger = new Exchanger<>(); new Thread(() -> exchangerTest.a(exchanger)).start(); new Thread(() -> exchangerTest.b(exchanger)).start(); }}

 

转载于:https://www.cnblogs.com/gyli20170901/p/10931497.html

你可能感兴趣的文章
使用wxWidgets for C++从资源文件中静态装载图像
查看>>
提高数据库安全性的办法
查看>>
工作流编程循序渐进(8:状态机工作流)
查看>>
3.VMware View 4.6安装与部署-connection server(View Standard Server)
查看>>
Lync Server 2013 实战系列之六:标准版-安装和更新LyncServer 系统
查看>>
MariaDB日志审计 帮你揪出内个干坏事儿的小子
查看>>
Reporting Services目录临时数据库文件存在
查看>>
一个Windows Mobile, Windows Embedded CE工程师的找工经历(一)
查看>>
终于有了MSDN上的Blog
查看>>
PHPUnit学习03---使用Mock对象解决测试依赖
查看>>
java类型与Hadoop类型之间的转换
查看>>
允许SQL Server 2005远程连接
查看>>
微软为asp.net ajax和jquery创建了CDN
查看>>
Chris:怎样成为一名Android应用开发
查看>>
常见的makefile写法【转】
查看>>
emmet,jade,haml, slim,less,sass,coffeescript等的实战优缺点
查看>>
和菜鸟一起学linux总线驱动之初识spi驱动数据传输流程【转】
查看>>
WorkFlow设计篇Step.4—异常处理(续)-WF4.0
查看>>
GNU make manual 翻译( 一百零三)
查看>>
深入浅出 React Native:使用 JavaScript 构建原生应用
查看>>