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){
                    //不作处理
                }                
            }    
        });        
    }
}

 

posted on 2016-01-20 20:01  沈小洋  阅读(273)  评论(0编辑  收藏  举报

导航