线程高级应用-心得6-java5线程并发库中同步工具类(synchronizers),新知识大用途

1.新知识普及

  1 2. Semaphore工具类的使用案例
  2 package com.java5.thread.newSkill;
  3 
  4 import java.util.concurrent.ExecutorService;
  5 import java.util.concurrent.Executors;
  6 import java.util.concurrent.Semaphore;
  7 
  8 /**
  9  * Semaphore工具类的使用案例
 10  * 跟互斥锁有点相似,只是互斥锁只有一把,信号灯可以有多个
 11  * Semaphore:信号灯
 12  */
 13 public class SemaphoreTest {
 14 
 15     
 16     public static void main(String[] args) {
 17         
 18         ExecutorService service = Executors.newCachedThreadPool();
 19         //
 20         final Semaphore sp = new Semaphore(3);
 21         for(int i=0;i<10;i++){
 22             Runnable runnable = new Runnable() {
 23                 
 24                 @Override
 25                 public void run() {
 26                     try {
 27                         //acquire:获得;下面方法是获取信号灯
 28                         sp.acquire();
 29                     } catch (InterruptedException e) {
 30                         e.printStackTrace();
 31                     }
 32                     //availablePermits():可以获得的许可
 33                     System.out.println("线程 "+Thread.currentThread().getName()+" 进入,当前已有 "+(3-sp.availablePermits())+" 个并发!");
 34                     
 35                     try {
 36                         Thread.sleep((long)Math.random()*10000);
 37                     } catch (InterruptedException e) {
 38                         e.printStackTrace();
 39                     }
 40                     System.out.println("线程 "+Thread.currentThread().getName()+" 即将离开!");
 41                     //释放信号灯
 42                     sp.release();
 43                     //下面代码有时候执行不准确
 44                     System.out.println("线程 "+Thread.currentThread().getName()+" 离开,当前已有 "+(3-sp.availablePermits())+" 个并发!");
 45                     
 46                 }
 47             };
 48             service.execute(runnable);
 49         }
 50 
 51     }
 52 }
 53 
 54 /*
 55  * 运行结果:
 56 线程 pool-1-thread-1 进入,当前已有 1 个并发!
 57 线程 pool-1-thread-1 即将离开!
 58 线程 pool-1-thread-1 离开,当前已有 0 个并发!
 59 线程 pool-1-thread-1 进入,当前已有 1 个并发!
 60 线程 pool-1-thread-1 即将离开!
 61 线程 pool-1-thread-1 离开,当前已有 0 个并发!
 62 线程 pool-1-thread-1 进入,当前已有 1 个并发!
 63 线程 pool-1-thread-3 进入,当前已有 2 个并发!
 64 线程 pool-1-thread-1 即将离开!
 65 线程 pool-1-thread-1 离开,当前已有 1 个并发!
 66 线程 pool-1-thread-3 即将离开!
 67 线程 pool-1-thread-3 离开,当前已有 0 个并发!
 68 线程 pool-1-thread-3 进入,当前已有 1 个并发!
 69 线程 pool-1-thread-1 进入,当前已有 2 个并发!
 70 线程 pool-1-thread-3 即将离开!
 71 线程 pool-1-thread-3 离开,当前已有 1 个并发!
 72 线程 pool-1-thread-1 即将离开!
 73 线程 pool-1-thread-1 离开,当前已有 0 个并发!
 74 线程 pool-1-thread-1 进入,当前已有 1 个并发!
 75 线程 pool-1-thread-5 进入,当前已有 2 个并发!
 76 线程 pool-1-thread-1 即将离开!
 77 线程 pool-1-thread-1 离开,当前已有 1 个并发!
 78 线程 pool-1-thread-5 即将离开!
 79 线程 pool-1-thread-5 离开,当前已有 0 个并发!
 80 线程 pool-1-thread-2 进入,当前已有 1 个并发!
 81 线程 pool-1-thread-2 即将离开!
 82 线程 pool-1-thread-2 离开,当前已有 0 个并发!
 83 线程 pool-1-thread-4 进入,当前已有 1 个并发!
 84 线程 pool-1-thread-4 即将离开!
 85 线程 pool-1-thread-4 离开,当前已有 0 个并发!
 86 
 87  */
 88 3. CyclicBarrier工具类的使用案例
 89 package com.java5.thread.newSkill;
 90 
 91 import java.util.concurrent.CyclicBarrier;
 92 import java.util.concurrent.ExecutorService;
 93 import java.util.concurrent.Executors;
 94 
 95 /**
 96  * CyclicBarrier工具类的使用案例
 97  *   应用场景:各个线程彼此等待,到齐后集体出发
 98  * cyclic:循环的,周期性的
 99  * barrier:障碍物,屏障  
100  */
101 public class CyclicBarrierTest {
102 
103     public static void main(String[] args) {
104         
105         ExecutorService service = Executors.newCachedThreadPool();
106         final CyclicBarrier cb = new CyclicBarrier(3);
107         for(int i=0;i<3;i++){
108             Runnable runnable= new Runnable() {
109                 
110                 @Override
111                 public void run() {
112                     try {
113                         Thread.sleep((long)Math.random()*10000);
114                         //cb.getNumberWaiting()+1;是因为该方法获取的数量是从0开始的
115                         System.out.println("线程 "+ Thread.currentThread().getName()+" 即将到达集合地点1,当前已有 "+(cb.getNumberWaiting()+1)+"已经到达;"+(cb.getNumberWaiting()==2?"都到齐了,继续走啊!":"正在等候!"));
116                         //想在什么地方集合就在什么地方await()等待
117                         cb.await();
118                         
119                         Thread.sleep((long)Math.random()*10000);
120                         System.out.println("线程 "+ Thread.currentThread().getName()+" 即将到达集合地点2,当前已有 "+(cb.getNumberWaiting()+1)+"已经到达;"+(cb.getNumberWaiting()==2?"都到齐了,继续走啊!":"正在等候!"));
121                         
122                         cb.await();
123                         
124                         Thread.sleep((long)Math.random()*10000);
125                         System.out.println("线程 "+ Thread.currentThread().getName()+" 即将到达集合地点3,当前已有 "+(cb.getNumberWaiting()+1)+"已经到达;"+(cb.getNumberWaiting()==2?"都到齐了,继续走啊!":"正在等候!"));
126                     
127                         cb.await();
128                     } catch (Exception e) {
129                         e.printStackTrace();
130                     }
131                 }
132             };
133             service.execute(runnable);
134         }
135         service.shutdown();
136     }
137 
138 }
139 
140 /*
141  * 运行结果:
142 线程 pool-1-thread-2 即将到达集合地点1,当前已有 1已经到达;正在等候!
143 线程 pool-1-thread-3 即将到达集合地点1,当前已有 2已经到达;正在等候!
144 线程 pool-1-thread-1 即将到达集合地点1,当前已有 3已经到达;都到齐了,继续走啊!
145 线程 pool-1-thread-2 即将到达集合地点2,当前已有 1已经到达;正在等候!
146 线程 pool-1-thread-1 即将到达集合地点2,当前已有 2已经到达;正在等候!
147 线程 pool-1-thread-3 即将到达集合地点2,当前已有 3已经到达;都到齐了,继续走啊!
148 线程 pool-1-thread-3 即将到达集合地点3,当前已有 1已经到达;正在等候!
149 线程 pool-1-thread-2 即将到达集合地点3,当前已有 2已经到达;正在等候!
150 线程 pool-1-thread-1 即将到达集合地点3,当前已有 3已经到达;都到齐了,继续走啊!
151 */
152 
153 4. CountDownLacth工具类的使用案例
154 package com.java5.thread.newSkill;
155 
156 import java.util.concurrent.CountDownLatch;
157 import java.util.concurrent.ExecutorService;
158 import java.util.concurrent.Executors;
159 
160 /**
161  * CountDownLacth工具类的使用案例
162  * 犹如倒计时计数器
163  * latch:门闩,闩门
164  * 应用场景:运动员比赛;裁判计时!一款比赛小游戏
165  * 下面例子:三个线程好比三个运动员,主线程好比一个裁判
166  */
167 public class CountDownLatchTest {
168 
169     public static void main(String[] args) {
170 
171         ExecutorService service = Executors.newCachedThreadPool();
172         
173         //设置一个数量为1的计时器
174         final CountDownLatch cdOrder = new CountDownLatch(1);
175         //设置一个数量为3的计时器
176         final CountDownLatch cdAnswer = new CountDownLatch(3);
177         for(int i=0;i<3;i++){
178             Runnable runnable= new Runnable() {
179                 
180                 @Override
181                 public void run() {
182                     try {
183                         System.out.println("线程 "+ Thread.currentThread().getName()+"正准备接受命令!");
184                         
185                         /*开启三个线程,都在这里等待;
186                          * 如何开始下一步呢!?就是再开启一个主线程来用countDown()方法;
187                          * 来进行减数,减到0就可以进行下一步程序
188                          */
189                         cdOrder.await();
190                         
191                         System.out.println("线程 "+ Thread.currentThread().getName()+"已接受命令!");
192                         Thread.sleep((long)Math.random()*10000);
193                         System.out.println("线程 "+ Thread.currentThread().getName()+"回应命令处理结果!");
194                         
195                         //countDown();方法就是将计数器身上的计数减1
196                         cdAnswer.countDown();
197                     
198                     } catch (Exception e) {
199                         e.printStackTrace();
200                     }
201                 }
202             };
203             service.execute(runnable);
204         }
205         try {
206             Thread.sleep((long)Math.random()*10000);
207             System.out.println("线程 "+ Thread.currentThread().getName()+"即将发布命令!");
208             
209             cdOrder.countDown();
210             
211             System.out.println("线程 "+ Thread.currentThread().getName()+"已发送命令,正在等待结果!");
212 
213             cdOrder.await();
214             
215             System.out.println("线程 "+ Thread.currentThread().getName()+"已收到所有响应结果!");
216             
217             cdAnswer.countDown();
218         
219         } catch (Exception e) {
220             e.printStackTrace();
221         }
222         service.shutdown();
223     }
224 
225 }
226 5. Exchanger工具类的使用案例
227 package com.java5.thread.newSkill;
228 
229 import java.util.concurrent.Exchanger;
230 import java.util.concurrent.ExecutorService;
231 import java.util.concurrent.Executors;
232 
233 /**
234  * Exchanger工具类的使用案例
235  * 应用场景:交易性应用或游戏
236  *   两个人碰在一起,交换彼此的数据
237  */
238 public class ExchangerTest {
239 
240     public static void main(String[] args) {
241         
242         ExecutorService service = Executors.newCachedThreadPool();
243         final Exchanger exchanger = new Exchanger();
244         service.execute(new Runnable() {
245             
246             @Override
247             public void run() {
248                 try{
249                     
250                     String data1 = "杨凯";
251                     System.out.println("线程 "+Thread.currentThread().getName()+" 正在把数据: "+data1+" 换出去!");
252                     
253                     Thread.sleep((long)Math.random()*10000);
254                     
255                     String data2 = (String) exchanger.exchange(data1);
256                     System.out.println("线程 "+Thread.currentThread().getName()+" 换回的数据为:"+data2);
257                 }catch(Exception e){
258                     
259                 }
260             }
261         });
262         service.execute(new Runnable() {
263             
264             @Override
265             public void run() {
266                 try{
267                     
268                     String data1 = "杨旋";
269                     System.out.println("线程 "+Thread.currentThread().getName()+" 正在把数据: "+data1+" 换出去!");
270                     
271                     Thread.sleep((long)Math.random()*10000);
272                     
273                     String data2 = (String) exchanger.exchange(data1);
274                     System.out.println("线程 "+Thread.currentThread().getName()+" 换回的数据为:"+data2);
275                 }catch(Exception e){
276                     
277                 }
278             }
279         });
280 
281     }
282 
283 }

 

posted @ 2017-01-08 13:47  chenxiangxiang  阅读(289)  评论(0编辑  收藏  举报