Java线程知识__其他几种线程同步的工具类的使用(CyclicBarrier,CountDownLatch,Exchanger)
2014-07-22 20:48
876 查看
1,CyclicBarrier类,表示指定数量的线程都在等待吗,只有到齐了才出发进行下面的步骤。
就相当于我们一个班出去春游,规定在图书馆集合,有的同学先到,有的后到,但是先到的
不能先走只有等到全部来齐了,才能上车出发。
示例:模拟同学们出去春游,只有人都到齐了才能进入下一个景点。
2,CountDownLatch类,该类就像是一个倒计时计数器。调用它的countDown()方法将计数器减一,当计数器到达0时,则所有
等待或者单个等待者开始执行。例如要实现一个人(也可以是多个人)等待其他所有人来通知他。可以实现一个人通知多个人
的效果,也可以实现多个人通知一个人的效果。类似裁判一声令下,等待的运动员都开始向前跑。或者当所有运动员到达终
点时,裁判才开始公布结果。
3,Exchangeer工具类。(可以在对中对元素进行配对和交换的线程的同步点.)
该类实现两个线程彼此交换数据的过程,当一个线程先打达时,另一个没有到达,那么这个线程会等待
另一个的到来,知道另一个到来了,彼此开始交换数据,交换完后两线程结束,否则其中一个将一直处于
阻塞,等待另一个的到来。
示例:模拟两个人交换数据的过程。
就相当于我们一个班出去春游,规定在图书馆集合,有的同学先到,有的后到,但是先到的
不能先走只有等到全部来齐了,才能上车出发。
示例:模拟同学们出去春游,只有人都到齐了才能进入下一个景点。
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /* * 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动, * 但它不会在启动 barrier 时执行预定义的操作。 */ public class CyclicBarrierTest { public static void main(String[] args) { ExecutorService pools = Executors.newCachedThreadPool(); final CyclicBarrier cb = new CyclicBarrier(3); for(int i=0;i<3;i++) { Runnable r = new Runnable() { @Override public void run() { try { Thread.sleep((long) (Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "到达集合点1," + "当前已有:" + (cb.getNumberWaiting() + 1) + "个线程在等待"); cb.await(); Thread.sleep((long) (Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "到达集合点2," + "当前已有:" + (cb.getNumberWaiting() + 1) + "个线程在等待"); cb.await(); Thread.sleep((long) (Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "到达集合点3," + "当前已有:" + (cb.getNumberWaiting() + 1) + "个线程在等待"); cb.await(); Thread.sleep((long) (Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "到达集合点4," + "当前已有:" + (cb.getNumberWaiting() + 1) + "个线程在等待"); cb.await(); } catch (Exception e) { e.printStackTrace(); } } }; pools.execute(r); } } }
2,CountDownLatch类,该类就像是一个倒计时计数器。调用它的countDown()方法将计数器减一,当计数器到达0时,则所有
等待或者单个等待者开始执行。例如要实现一个人(也可以是多个人)等待其他所有人来通知他。可以实现一个人通知多个人
的效果,也可以实现多个人通知一个人的效果。类似裁判一声令下,等待的运动员都开始向前跑。或者当所有运动员到达终
点时,裁判才开始公布结果。
import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /* * 模拟运动员赛跑的过程,运动员等待裁判发命令,当裁判发命令后运动员起跑,只有当所有运动员到达终点后,裁判才能公布 * 结果。 */ public class CountDownLatchTest { public static void main(String[] args) { ExecutorService pool = Executors.newCachedThreadPool(); //裁判计时器对象 final CountDownLatch cdOrder = new CountDownLatch(1); //创建运动员达到获取结果计时器对象 final CountDownLatch cdAnswer = new CountDownLatch(3); for(int i=0;i<3;i++) { Runnable command = new Runnable() { @Override public void run() { try { System.out.println("线程" + Thread.currentThread().getName() + "正在准备接受命令"); cdOrder.await(); System.out.println("线程" + Thread.currentThread().getName() + "已经接受命令"); Thread.sleep((long) (Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "等待比赛结果"); cdAnswer.countDown(); } catch (Exception e) { e.printStackTrace(); } } }; pool.execute(command); } //裁判在主线程中等待另外一个计数器为零 try { Thread.sleep((long) (Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将发出命令"); cdOrder.countDown(); System.out.println("线程" + Thread.currentThread().getName() + "已经发出命令,等待所有用户达到,公布结果"); cdAnswer.await(); System.out.println("所有用户已经到达,线程" + Thread.currentThread().getName() + "已经公布结果"); } catch (Exception e) { e.printStackTrace(); } } }
3,Exchangeer工具类。(可以在对中对元素进行配对和交换的线程的同步点.)
该类实现两个线程彼此交换数据的过程,当一个线程先打达时,另一个没有到达,那么这个线程会等待
另一个的到来,知道另一个到来了,彼此开始交换数据,交换完后两线程结束,否则其中一个将一直处于
阻塞,等待另一个的到来。
示例:模拟两个人交换数据的过程。
import java.util.Random; import java.util.concurrent.Exchanger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /* * 两个线程彼此交换数据,只有当两个都到达后才交换数据,线程结束。 */ public class ExchangerTest { public static void main(String[] args) { ExecutorService pool = Executors.newCachedThreadPool(); //创建交换器对象 final Exchanger<String> exchanger = new Exchanger<>(); //向线程池添加两个任务 pool.execute(new Runnable() { @Override public void run() { try { String data1 = "第一个人的数据"; System.out.println("第一个人正在把" + data1 + "交换出去" ); Thread.sleep(new Random().nextInt(1000)); String data2 = exchanger.exchange(data1); System.out.println("第一个人换回的数据为:" + data2); } catch (Exception e) { // TODO: handle exception } } }); pool.execute(new Runnable() { @Override public void run() { try { String data1 = "第二个人的数据"; System.out.println("第二个人正在把" + data1 + "交换出去" ); Thread.sleep(new Random().nextInt(1000)); String data2 = exchanger.exchange(data1); System.out.println("第二个人换回的数据为:" + data2); } catch (Exception e) { // TODO: handle exception } } }); } }
相关文章推荐
- Java_并发线程_Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- Java_并发线程_Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- Java并发编程之2——同步工具类的使用(CountDownLatch,CyclicBarrier,BlockungQueue,Semaphore)
- Java线程计数器CyclicBarrier和CountDownLatch的使用
- java高并发程序设计总结五:jdk并发包其他同步控制工具类:ReadWriteLock/CountDownLatch/CyclicBarrier/LockSupport
- 第8章 Java中的并发工具类(CountDownLatch CyclicBarrier Semaphore Exchanger)
- Java多线程(八)之Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- JAVA多线程系列--并发工具类(CountDownLatch, CyclicBarrier, Semaphore,Exchanger)
- 多线程并发常用类:condition,semaphore,CyclicBarrier,countdownlatch,exchanger使用整理
- Java CountDownLatch 和 CyclicBarrier 使用
- Java:多线程等待所有线程结束(CountDownLatch/CyclicBarrier) .
- 黑马程序员-Condition条件对象、Semaphore、CyclicBarrier、倒计时门栓 CountDownLatch、Exchanger(实现两个线程之间数据交换
- Java多线程等待所有线程结束(CountDownLatch/CyclicBarrier)
- 《Java 7 并发编程指南》学习概要 (3)Semaphore, CountDownLatch, CyclicBarrier , Phaser, Exchanger
- Java多线程(八)之Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- Java中CountDownLatch和CyclicBarrier的使用和比较
- Java:多线程等待所有线程结束(CountDownLatch/CyclicBarrier) .
- Java:多线程等待所有线程结束(CountDownLatch/CyclicBarrier)
- java.util.concurrent 下的Semaphore CyclicBarrier CountDownLatch 分析使用