CyclicBarrier的应用封装

137 阅读2分钟

最近看到一篇文章,【死磕Java并发】-----J.U.C之并发工具类:CyclicBarrier - 掘金 (juejin.cn) ,其中讲解了CyclicBarrier的源码方法做了分析并给出了一个应用案例。

但感觉这种使用很不美观,如果在使用CyclicBarrier时,还要关注非业务的语法使用,那估计就不太想用,所以就想着是不是封装一下,让人使用的时候直接关注业务逻辑处理,而不用去看那些非逻辑部分的东西,所以就有了接下来的尝试:

想自己试着封装使用,一方面是有助于加深对CyclicBarrier的应用理解,另一方面也是尝试一下,积累一些封装设计的技巧。

不啰嗦了,直接上代码:


import java.util.List;

public interface ProcessHandler<T, R, RT> {

   public R process(List<T> data);

   public RT finalProcess(List<R> data);

}

import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

public class WorkHelper<T, R, RT> {

    private List<T> data;

    private Integer workerNum;

    private ProcessHandler<T, R, RT> handler;

    private List<R> result = new ArrayList<>();

    private CyclicBarrier cyclicBarrier;

    private WorkHelper(List<T> data, Integer workerNum, ProcessHandler<T, R, RT> handler) {
        this.data = data;
        this.workerNum = workerNum;
        this.handler = handler;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public Integer getWorkerNum() {
        return workerNum;
    }

    public void setWorkerNum(Integer workerNum) {
        this.workerNum = workerNum;
    }

    public ProcessHandler<T, R, RT> getHandler() {
        return handler;
    }

    public void setHandler(ProcessHandler<T, R, RT> handler) {
        this.handler = handler;
    }

    public static WorkHelper.WorkHelperBuilder builder(){
        return new WorkHelper.WorkHelperBuilder();
    }


    public void execute(){
        cyclicBarrier = new CyclicBarrier(this.workerNum, () -> this.handler.finalProcess(result));
        Map<Integer, List<T>> pieces = getPieces(this.data);

        for (int i = 0; i < this.workerNum; i++) {
            new CyclicThread(this.handler, pieces.get(i)).start();
        }
    }

    public Map<Integer, List<T>> getPieces(List<T> list) {
        Map<Integer, List<T>> map = new HashMap<>();

        for (int i = 0; i < list.size(); i++) {
            int locate = i % this.workerNum;
            if (ObjectUtils.isEmpty(map.get(locate)))
                map.put(locate, new ArrayList<>());
            map.get(locate).add(list.get(i));
        }

        return map;
    }

    static class WorkHelperBuilder<T, R, RT> {

        private List<T> data;

        private Integer workerNum;

        private ProcessHandler<T, R, RT> handler;

        public WorkHelperBuilder data(final List<T> data) {
            this.data = data;
            return this;
        }

        public WorkHelperBuilder workerNum(final Integer workerNum) {
            this.workerNum = workerNum;
            return this;
        }

        public WorkHelperBuilder handler(final ProcessHandler<T, R, RT> handler) {
            this.handler = handler;
            return this;
        }

        public WorkHelper build(){
            return new WorkHelper(this.data, this.workerNum, this.handler);
        }
    }

    class CyclicThread extends Thread {

        private ProcessHandler<T,R, RT> handler;

        private List<T> data;

        public CyclicThread(ProcessHandler<T,R, RT> handler, List<T> data){
            this.handler = handler;
            this.data = data;
        }

        @Override
        public void run() {
            R process = handler.process(this.data);
            result.add(process);
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}

测试

import java.util.List;

public class PrintProcess implements ProcessHandler<String, List<String>, String>{

    @Override
    public List<String> process(List<String> data) {
        System.out.println(Thread.currentThread().getName() + " : " + data + " Coming...");
        return null;
    }

    @Override
    public String finalProcess(List<List<String>> result) {
        System.out.println(":::::::: 全局数据处理 ::::::::");
        System.out.println(Thread.currentThread().getName() + " ,It is time to Party...");
        return null;
    }
}
import java.util.*;

public class Test {

    public static void main(String[] args) {
        WorkHelper worker = WorkHelper.builder()
                .data(Arrays.asList("Hello","Five","Boy","Coming", "Home", "With"))
                .workerNum(5)
                .handler(new PrintProcess()).build();

        worker.execute();
    }

}