• 线程高级应用-心得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 }
  • 相关阅读:
    面试常考知识点——Java(JVM,JDK,JRE)
    使用CSS transform属性的skewX、skewY沿X、Y轴倾斜元素
    视觉设计应用
    小程序
    小程序获取用户的登录头像和用户名
    整站建设
    2018-05-05(在小程序中使用图标)
    2018-05-03(PHP)
    webpack
    简历
  • 原文地址:https://www.cnblogs.com/cxxjohnson/p/6261900.html
Copyright © 2020-2023  润新知