最近看到一篇文章,【死磕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();
}
}