zoukankan      html  css  js  c++  java
  • JavaThread的其他同步工具类

    1、CyclicBarrier

    主要用于控制同步线程数量,表示多个线程之间彼此等待,所有的线程就绪之后才可以继续运行。不论有多少个线程,只要有一个线程未完成,那么其他所有的线程都将处于等待状态。这就好比大家相约出游,要集合好之后才能出发,分散活动后又在指定地点集合碰面,才能进行下一步的活动。
    示例代码:

    public class CyclicBarrierTest {
    
        public static void main(String[] args) {
            ExecutorService service = Executors.newCachedThreadPool();
            //这里新建一个包含3个同步线程的CyclicBarrier对象
            final  CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
            for(int i=0;i<3;i++){
                Runnable runnable = new Runnable(){
                        public void run(){
                        try {
                            Thread.sleep((long)(Math.random()*10000));    
                            System.out.println("线程" + Thread.currentThread().getName() + 
                                    "即将到达集合地点1,当前已有" + (cyclicBarrier.getNumberWaiting()+1) + "个已经到达," +
                                    (cyclicBarrier.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));                        
                            cyclicBarrier.await();
                            Thread.sleep((long)(Math.random()*10000));    
                            System.out.println("线程" + Thread.currentThread().getName() + 
                                    "即将到达集合地点2,当前已有" + (cyclicBarrier.getNumberWaiting()+1) + "个已经到达," +
                                    (cyclicBarrier.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));
                            cyclicBarrier.await();    
                            Thread.sleep((long)(Math.random()*10000));    
                            System.out.println("线程" + Thread.currentThread().getName() + 
                                    "即将到达集合地点3,当前已有" + (cyclicBarrier.getNumberWaiting() + 1) + "个已经到达," +
                                    (cyclicBarrier.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));                        
                            cyclicBarrier.await();                        
                        } catch (Exception e) {
                            e.printStackTrace();
                        }                
                    }
                };
                service.execute(runnable);
            }
            service.shutdown();
        }
    }

    2、CountDownLatch

    犹如倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当计数器到达0时,则所有等待者或单个等待者开始执行。这直接通过代码来说明CountDownLatch的作用,这样理解更直接。

    可以实现1个人(也可以是多个人)等待其他所有人来通知他,可以实现一个人通知多个人的效果,类似裁判一声口令,运动员开始奔跑,或者所有运动员都跑到终点后裁判才可以公布结果,用这个功能可以实现百米赛跑的游戏程序!还可以实现一个计划需要多个领导都签字后才能继续向下实施的情况。

    示例代码:

    public class CountdownLatchTest {
    
        public static void main(String[] args) {
            ExecutorService service = Executors.newCachedThreadPool();
            final CountDownLatch cdOrder = new CountDownLatch(1);
            final CountDownLatch cdAnswer = new CountDownLatch(3);        
            for(int i=0;i<3;i++){
                Runnable runnable = new Runnable(){
                        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();
                        }                
                    }
                };
                service.execute(runnable);
            }        
            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();
            }                
            service.shutdown();
        }
    }

    3、Exchanger

    主要用于交换两个线程之间的数据

    示例代码:

    public class ExchangerTest {
    
        public static void main(String[] args) {
            ExecutorService service = Executors.newCachedThreadPool();
            final Exchanger exchanger = new Exchanger();
            service.execute(new Runnable(){
                public void run() {
                    try {                
                        String data1 = "shen_smile";
                        System.out.println("线程" + Thread.currentThread().getName() + 
                        "正在把数据" + data1 +"换出去");
                        Thread.sleep((long)(Math.random()*10000));
                        String data2 = (String)exchanger.exchange(data1);
                        System.out.println("线程" + Thread.currentThread().getName() + 
                        "换回的数据为" + data2);
                    }catch(Exception e){
                        //不作处理
                    }
                }    
            });
            service.execute(new Runnable(){
                public void run() {
                    try {                
                        String data1 = "ExchangerTest";
                        System.out.println("线程" + Thread.currentThread().getName() + 
                        "正在把数据" + data1 +"换出去");
                        Thread.sleep((long)(Math.random()*10000));                    
                        String data2 = (String)exchanger.exchange(data1);
                        System.out.println("线程" + Thread.currentThread().getName() + 
                        "换回的数据为" + data2);
                    }catch(Exception e){
                        //不作处理
                    }                
                }    
            });        
        }
    }
  • 相关阅读:
    light oj 1105 规律
    light oj 1071 dp(吃金币升级版)
    light oj 1084 线性dp
    light oj 1079 01背包
    light oj 1068 数位dp
    light oj 1219 树上贪心
    light oj 1057 状压dp TSP
    light oj 1037 状压dp
    矩阵快速幂3 k*n铺方格
    矩阵快速幂2 3*n铺方格
  • 原文地址:https://www.cnblogs.com/shen-smile/p/5146386.html
Copyright © 2011-2022 走看看