多线程CyclicBarrier与CountDownLatch使用示例

多线程最典型的需求场景一般是:有的时候为了获取性能,需要各个业务并行获取并处理数据,同时返回处理好的数据,这时候多线程就派上用处了。

对这个场景,最简单的代码实现是可以使用CyclicBarrier或CountDownLatch;

话不多说,直接上代码:

 测试主类-MainThread:

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

/**
 * shiroexample
 * functional describe:
 *
 * @author DR.YangLong [[email protected]]
 * @version 1.0 2015/4/13 9:22
 */
public class MainThread extends Thread{
    private Map<String,Object> resultMap;

    public MainThread(Map<String, Object> resultMap) {
        this.resultMap = resultMap;
    }

    @Override
    public void run() {
        System.out.println("实验2到主线程了,取出结果:");
        Iterator<String> iterator=resultMap.keySet().iterator();
        while (iterator.hasNext()){
            String name=iterator.next();
            System.out.println("线程:" + resultMap.get(name));
        }
        System.out.println("实验2等待线程结束。");
    }

    public static void main(String[] args){
        /***
         * 障碍器测试
         */
        Map<String,Object> resultMap=new ConcurrentHashMap<String, Object>(6);
        CyclicBarrier cyclicBarrier=new CyclicBarrier(5);//实验1:主线等待其他线程
        //CyclicBarrier cyclicBarrier=new CyclicBarrier(4,new MainThread(resultMap));//实:2:一般性并行其他线程执行完执行某个线程。
        new ThreadService("CyclicBarrier服务1",cyclicBarrier,resultMap).start();
        new ThreadService("CyclicBarrier服务2",cyclicBarrier,resultMap).start();
        new ThreadService("CyclicBarrier服务3",cyclicBarrier,resultMap).start();
        new ThreadService("CyclicBarrier服务4",cyclicBarrier,resultMap).start();
        //以下为实验1内容,实验2时注释掉
        try {
            System.out.println("当前线程等待其他线程");
            cyclicBarrier.await();
            System.out.println("当前等待结束,开始执行,取出结果:");
            Iterator<String> iterator=resultMap.keySet().iterator();
            while (iterator.hasNext()){
                String name=iterator.next();
                System.out.println("线程:" + resultMap.get(name));
            }
            System.out.println("当前线结束。");
        } catch (Exception e) {
            e.printStackTrace();
        }

        /***
         * 计数数器测试
         */
        resultMap.clear();
        CountDownLatch countDownLatch=new CountDownLatch(4);
        new CountDownService("CountDownLatch服务A",countDownLatch,resultMap).start();
        new CountDownService("CountDownLatch服务B",countDownLatch,resultMap).start();
        new CountDownService("CountDownLatch服务C",countDownLatch,resultMap).start();
        new CountDownService("CountDownLatch服务D",countDownLatch,resultMap).start();
        try {
            System.out.println("CountDownLatch当前线程等待。");
            countDownLatch.await();//等待并行线程完成工作
            System.out.println("CountDownLatch当前线程等待结束,开始执行,取出结果:");
            Iterator<String> iterator=resultMap.keySet().iterator();
            while (iterator.hasNext()){
                String name=iterator.next();
                System.out.println("线程:" + resultMap.get(name));
            }
            System.out.println("CountDownLatch当前线程结束。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

    CyclicBarrier 测试使用的service,ThreadService:

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

/**
 * shiroexample
 * functional describe:
 *
 * @author DR.YangLong [[email protected]]
 * @version 1.0 2015/4/13 9:12
 */
public class ThreadService extends Thread{
    private String name;
    private CyclicBarrier cyclicBarrier;
    private Map<String,Object> resultMap;

    public ThreadService(String name, CyclicBarrier cyclicBarrier,Map<String,Object> resultMap) {
        this.name = name;
        this.cyclicBarrier = cyclicBarrier;
        this.resultMap=resultMap;
    }

    @Override
    public void run() {
        System.out.println("子线程"+this.name+"正在执行!");
        try {
            resultMap.put(this.name,this.name);
            Thread.sleep(1000);
            System.out.println("子线程"+this.name+"执行完成!");
            cyclicBarrier.await();//计数器-1
          //添加日志等操作在下面,当计数器为0时执行
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


CountDownLatch 测试使用Service CountDownService:

import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * shiroexample
 * functional describe:
 *
 * @author DR.YangLong [[email protected]]
 * @version 1.0 2015/4/13 10:01
 */
public class CountDownService extends Thread{
    private String name;
    private CountDownLatch countDownLatch;
    private Map<String,Object> resultMap;

    public CountDownService(String name, CountDownLatch countDownLatch,Map<String,Object> resultMap) {
        this.name = name;
        this.countDownLatch = countDownLatch;
        this.resultMap=resultMap;
    }

    @Override
    public void run() {
        System.out.println("子线程" + this.name + "正在执行!");
        try {
            resultMap.put(this.name,this.name);
            Thread.sleep(1000);
            System.out.println("子线程"+this.name+"执行完成!");
            countDownLatch.countDown();//计数器-1
            //添加日志等操作在下面,当计数器为0时执行
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行结果:

当前线程等待其他线程
子线程CyclicBarrier服务1正在执行!
子线程CyclicBarrier服务2正在执行!
子线程CyclicBarrier服务3正在执行!
子线程CyclicBarrier服务4正在执行!
子线程CyclicBarrier服务1执行完成!
子线程CyclicBarrier服务4执行完成!
子线程CyclicBarrier服务3执行完成!
子线程CyclicBarrier服务2执行完成!
当前等待结束,开始执行,取出结果:
线程:CyclicBarrier服务4
线程:CyclicBarrier服务1
线程:CyclicBarrier服务3
线程:CyclicBarrier服务2
当前线结束。
CyclicBarrier服务1日志处理......
CyclicBarrier服务4日志处理......
CyclicBarrier服务3日志处理......
CyclicBarrier服务2日志处理......
CountDownLatch当前线程等待。
子线程CountDownLatch服务A正在执行!
子线程CountDownLatch服务B正在执行!
子线程CountDownLatch服务C正在执行!
子线程CountDownLatch服务D正在执行!
子线程CountDownLatch服务A执行完成!
子线程CountDownLatch服务B执行完成!
CountDownLatch服务A日志处理......
CountDownLatch服务B日志处理......
子线程CountDownLatch服务D执行完成!
CountDownLatch服务D日志处理......
子线程CountDownLatch服务C执行完成!
CountDownLatch服务C日志处理......
CountDownLatch当前线程等待结束,开始执行,取出结果:
线程:CountDownLatch服务A
线程:CountDownLatch服务D
线程:CountDownLatch服务B
线程:CountDownLatch服务C
CountDownLatch当前线程结束。

  对于数据的取回,有2个方式,一个是使用单例的容器,另外一个是定义成属性,提供getter方法,运行完成后调用获取,但这又涉及到这2者的区别:

CyclicBarrier 阻塞所有调用await()的线程,等待计数器为0,所有线程【包括一个目标线程】才全部一起往下执行。

CountDownLatch 不阻塞所有线程【countDown()的线程不会被阻塞】,只阻塞调用await()的线程,当计数器为0时调用await()的线程继续往下执行。

所以,需要返回值在线程阻塞前完成封装,以确保主线程能够获得已完成封装的返回值。

你可能感兴趣的:(多线程获取其他线程返回值)