Java--CyclicBarrier同步屏障原理,使用

package com;

import java.util.Map;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CyclicBarrier;

/**
 * Created by yangyu on 16/11/28.
 */

/**
 * CyclicBarrier是一个同步屏障
 * CyclicBarrier让一个线程达到屏障时被阻塞,直到最后一个线程达到屏障时,屏障才会开门,所有被屏障拦截的线程才会继续执行
 * CyclicBarrier(int parties, Runnable barrierAction)构造函数,用于在所有线程都到达屏障后优先执行barrierAction的run()方法
 * CyclicBarrier使用场景:
 * 可以用于多线程计算以后,最后使用合并计算结果的场景;
 *
 * 以下列子就是:使用5个线程分别向Map中放置计算好的数据,最后由Action来执行合并结果的功能;
 *
 * 原理:
 * CyclicBarrier中有一个计数器,每当一个线程调用await()方法时计数器就会减1
 * 计数器不等于0时,会通过ReentrantLock重入所的condition的await()方法将线程阻塞
 * 直到计数器等于0时,会检测是否有barrierAction,如果有则执行barrierAction的run方法,然后唤醒signalAll()所有阻塞线程
 * 如果没有barrierAction则直接通过signalAll()唤醒所有阻塞线程
 */
public class TestCyclicBarrier {

    private static ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<String, Integer>();

    public static void main(String[] args) {
        /**
         * CyclicBarrier会阻塞5个线程,当5个线程都到达屏障时会优先执行Action的run()方法
         */
        CyclicBarrier c = new CyclicBarrier(5,new Action());
        for (int i = 0; i < 5; i++) {
            new Thread(()->{
                /**
                 * 将计算完成的结果放入Map中
                 */
                map.put(String.valueOf(Thread.currentThread().getId()),5);
                try {
                    /**
                     * 被屏障拦截
                     */
                    c.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    /**
     * 屏障开启后,优先执行Action的run()方法合并结果
     */
    private static class Action implements Runnable{

        @Override
        public void run() {
            int j=0;
            for (Map.Entry<String,Integer> entry : map.entrySet()){
                System.out.println(entry.getValue());
                j = j+entry.getValue();
            }
            System.out.println("j="+j);
        }
    }
}

 

posted @ 2016-11-28 11:31  11楼的日记  阅读(514)  评论(0编辑  收藏  举报