黑马程序员-Semaphore、CyclicBarrier、CountDownLatch、Exchanger
2013-03-05 23:08
573 查看
------- android培训、java培训、期待与您交流! ----------
信号灯同步Semaphore:
创建:Semaphore semaphore = new Semaphore(3);
获取:semaphore.acquire();
释放:semaphore.release();
获取剩余信号灯数量:semaphore.availablePermits();
信号灯在创建的时候就定义一个数字允许有多少个信号灯,有很多线程,在执行的时候获取信号灯,如果信号灯获取等于了创建的个数,其余线程就等待,每个线程结束前释放一个线程获取的信号灯,等待的线程就开始抢这个空出来的信号灯,也可以在创建信号灯的时候指定是否公平排队,如果在构造函数中多加一个true的话,这个空出来的信号灯是分配给在等待的第一个线程,如同notify()一样的机制。
信号灯可以有效的控制几个线程同时运行。
关卡CyclicBarrier:
创建:CyclicBarrier cb = new CyclicBarrier(3);// 创建对象并设置障碍需要3个线程一起通过
设置关卡:cb.await();
获得当前关卡前的线程数:cb.getNumberWaiting();//这个是从0开始记的,也就是说0就是代表有一个线程了。
这个可以用来制作游戏过关需要多少人啊,活动需要多少人参加才开启啊。
倒记时锁存器CountDownLatch:
创建:CountDownLatch cdl = new CountDownLatch(1);//计数器初始值为1
等待计数器为0:cdl.await();
计数器自减:cdl.countDown();
模拟运动员比赛等待裁判鸣枪,裁判等待所有运动员跑完然后公布结果。
控制台输出:
运动员pool-1-thread-1等待命令
运动员pool-1-thread-3等待命令
运动员pool-1-thread-2等待命令
裁判 main 鸣枪
裁判 main等待运动员跑完公布结果
运动员pool-1-thread-1等待结果
运动员pool-1-thread-3等待结果
运动员pool-1-thread-2等待结果
公布结果
交换工具类Exchanger:
创建:Exchanger exchanger = new Exchanger();
调用:String data2 = (String)exchanger.exchange(data1);
String data2 = (String)exchanger.exchange(data1,2,TimeUnit.SECONDS);//这种表示在交换过程等待的时间要在两秒以内,如果超过两秒会抛出超时异常。
信号灯同步Semaphore:
创建:Semaphore semaphore = new Semaphore(3);
获取:semaphore.acquire();
释放:semaphore.release();
获取剩余信号灯数量:semaphore.availablePermits();
信号灯在创建的时候就定义一个数字允许有多少个信号灯,有很多线程,在执行的时候获取信号灯,如果信号灯获取等于了创建的个数,其余线程就等待,每个线程结束前释放一个线程获取的信号灯,等待的线程就开始抢这个空出来的信号灯,也可以在创建信号灯的时候指定是否公平排队,如果在构造函数中多加一个true的话,这个空出来的信号灯是分配给在等待的第一个线程,如同notify()一样的机制。
1 public static void main(String[] args) { 2 // TODO Auto-generated method stub 3 // 创建一个缓存线程池 4 ExecutorService threadPool = Executors.newCachedThreadPool(); 5 // 创建有3个信号灯的信号灯对象 6 final Semaphore semaphore = new Semaphore(3); 7 for (int i = 0; i < 10; i++) { 8 new Thread(new Runnable() { 9 10 @Override 11 public void run() { 12 try { 13 // 获取一个信号灯 14 semaphore.acquire(); 15 System.out.println(Thread.currentThread().getName() + "进来了"); 16 Thread.sleep(1000); 17 //semaphore.availablePermits();获得剩余几个信号灯 18 System.out.println("还有几个坑呢? :" + semaphore.availablePermits()); 19 System.out.println(Thread.currentThread().getName() + "准备闪了"); 20 21 } catch (Exception e) { 22 23 }finally{ 24 // 释放一个信号灯 25 semaphore.release(); 26 } 27 } 28 }).start(); 29 } 30 }
信号灯可以有效的控制几个线程同时运行。
关卡CyclicBarrier:
创建:CyclicBarrier cb = new CyclicBarrier(3);// 创建对象并设置障碍需要3个线程一起通过
设置关卡:cb.await();
获得当前关卡前的线程数:cb.getNumberWaiting();//这个是从0开始记的,也就是说0就是代表有一个线程了。
这个可以用来制作游戏过关需要多少人啊,活动需要多少人参加才开启啊。
1 public static void main(String[] args) { 2 // TODO Auto-generated method stub 3 // 创建缓存线程池 4 ExecutorService threadPool = Executors.newCachedThreadPool(); 5 // 创建对象并设置障碍需要3个线程一起通过 6 final CyclicBarrier cb = new CyclicBarrier(3); 7 for (int i = 0; i < 3; i++) { 8 threadPool.execute(new Runnable() { 9 10 @Override 11 public void run() { 12 try { 13 Thread.sleep((int) (Math.random() * 1000)); 14 System.out.println(Thread.currentThread().getName() 15 + "等待"); 16 //获取等待个数从0开始算 17 if (cb.getNumberWaiting() == 2) 18 System.out.println("人齐了,走你!"); 19 // 设置关卡、障碍 20 cb.await(); 21 22 Thread.sleep((int) (Math.random() * 1000)); 23 System.out.println(Thread.currentThread().getName() 24 + "等待"); 25 if (cb.getNumberWaiting() == 2) 26 System.out.println("人齐了,再走你!"); 27 // 设置关卡、障碍 28 cb.await(); 29 } catch (Exception e) { 30 // TODO: handle exception 31 } 32 } 33 }); 34 } 35 }
倒记时锁存器CountDownLatch:
创建:CountDownLatch cdl = new CountDownLatch(1);//计数器初始值为1
等待计数器为0:cdl.await();
计数器自减:cdl.countDown();
模拟运动员比赛等待裁判鸣枪,裁判等待所有运动员跑完然后公布结果。
1 public static void main(String[] args) { 2 // TODO Auto-generated method stub 3 //创建缓存线程池 4 ExecutorService threadPool = Executors.newCachedThreadPool(); 5 //创建倒记时锁存器 ,计数器初始值为1 6 final CountDownLatch cdl = new CountDownLatch(1); 7 //计数器初始值为3 8 final CountDownLatch cdl2 = new CountDownLatch(3); 9 for(int i = 0; i < 3; i++){ 10 threadPool.execute(new Runnable() { 11 12 @Override 13 public void run() { 14 System.out.println("运动员"+Thread.currentThread().getName() + "等待命令"); 15 16 try { 17 //等待cdl计数器为0 18 cdl.await(); 19 Thread.sleep((int)(Math.random()*1000)); 20 System.out.println("运动员"+Thread.currentThread().getName() + "等待结果"); 21 22 //cdl2计数器自减 23 cdl2.countDown(); 24 } catch (Exception e) { 25 e.printStackTrace(); 26 } 27 } 28 }); 29 } 30 try { 31 Thread.sleep((int)(Math.random()*1000)); 32 33 System.out.println("裁判 " + Thread.currentThread().getName() + " 鸣枪"); 34 //cdl计数器自减 35 cdl.countDown(); 36 System.out.println("裁判 " + Thread.currentThread().getName() + "等待运动员跑完公布结果"); 37 //等待cdl2计数器为零 38 cdl2.await(); 39 System.out.println("公布结果"); 40 } catch (Exception e) { 41 // TODO: handle exception 42 } 43 }
控制台输出:
运动员pool-1-thread-1等待命令
运动员pool-1-thread-3等待命令
运动员pool-1-thread-2等待命令
裁判 main 鸣枪
裁判 main等待运动员跑完公布结果
运动员pool-1-thread-1等待结果
运动员pool-1-thread-3等待结果
运动员pool-1-thread-2等待结果
公布结果
交换工具类Exchanger:
创建:Exchanger exchanger = new Exchanger();
调用:String data2 = (String)exchanger.exchange(data1);
String data2 = (String)exchanger.exchange(data1,2,TimeUnit.SECONDS);//这种表示在交换过程等待的时间要在两秒以内,如果超过两秒会抛出超时异常。
1 public static void main(String[] args) { 2 // TODO Auto-generated method stub 3 //创建交换工具类 4 final Exchanger exchanger = new Exchanger(); 5 new Thread(new Runnable() { 6 7 @Override 8 public void run() { 9 // TODO Auto-generated method stub 10 try { 11 String data1 = "zhangsan"; 12 System.out.println(Thread.currentThread().getName() + "要把zhangsan换出去"); 13 // Thread.sleep(3000); 14 //交换时等待的时间要在2秒内,否则抛出超时异常:TimeoutException 15 //String data2 = (String)exchanger.exchange(data1,2,TimeUnit.SECONDS); 16 //交换 17 String data2 = (String)exchanger.exchange(data1); 18 System.out.println(Thread.currentThread().getName() + "得到的:" + data2); 19 } catch (Exception e) { 20 e.printStackTrace(); 21 } 22 } 23 }).start(); 24 new Thread(new Runnable() { 25 26 @Override 27 public void run() { 28 // TODO Auto-generated method stub 29 try { 30 String data1 = "lisi"; 31 System.out.println(Thread.currentThread().getName() + "要把lisi换出去"); 32 Thread.sleep(3000); 33 //交换 34 String data2 = (String)exchanger.exchange(data1); 35 System.out.println(Thread.currentThread().getName() + "得到的:" + data2); 36 } catch (InterruptedException e) { 37 e.printStackTrace(); 38 } 39 } 40 }).start(); 41 }
相关文章推荐
- 黑马程序员-Condition条件对象、Semaphore、CyclicBarrier、倒计时门栓 CountDownLatch、Exchanger(实现两个线程之间数据交换
- Join,CountDownLatch,CyclicBarrier,Semaphore和Exchanger
- 四个并发工具类CountDownLatch,CyclicBarrier,Semaphore,Exchanger
- 多线程编程的常用类(CountDownLatch, Semaphore, CyclicBarrier 和 Exchanger)
- java并发编程——八 理解分析并发组件-CountDownLatch\CyclicBarrier\Exchanger\Semaphore
- CyclicBarrier CountDownLatch Semaphore Exchanger
- 《Java 7 并发编程指南》学习概要 (3)Semaphore, CountDownLatch, CyclicBarrier , Phaser, Exchanger
- Java多线程(八)之Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- JAVA多线程系列--并发工具类(CountDownLatch, CyclicBarrier, Semaphore,Exchanger)
- Java_并发线程_Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- 第8章 Java中的并发工具类(CountDownLatch CyclicBarrier Semaphore Exchanger)
- Java多线程(八)之Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- 多线程并发常用类:condition,semaphore,CyclicBarrier,countdownlatch,exchanger使用整理
- Java多线程——同步器 Semaphore、 CountDownLatch、 CyclicBarrier 、Exchanger
- Java_并发线程_Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- java 并发编程 CountDownLatch、CyclicBarrier和 Semaphore
- Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore
- 并发工具类CountDownLatch、CyclicBarrier、Semaphore、Exchanger详解
- Java并发编程(十三):CountDownLatch、CyclicBarrier和Semaphore(转载)
- java 并发类semaphore countdownlatch cyclicbarrier reentrantlock condition reentrantreadwritelock