超线程:虚拟出多个核
并发与并行
并发可认为是一种程序的逻辑结构的设计模式
并行是程序执行的一种属性
对Java而言,对支持Concurrency(并发)/Parallelism(并行)的不断完善,明显地体现在优化并发与并行
•Java 1 支持threads, locks, condition queues
•Java 5 引入了 thread pools, blocking queues, concurrent collections
•Java 7 加入了fork-join库
•Java 8 加入了 parallel streams
分治法
把一个规模大的问题划分为规模较小的子问题,然后分而治之,最后合并子问题的解得到原问题的解。步骤:
在分治法中,子问题一般是相互独立的,因此,经常通过递归调用算法来求解子问题。
拆分任务
普通线程池递归计算任务
普通线程池递归计算任务存在的问题(需要等待前面的结果)
public Long call() throws Exception { // override
System.out.format("%s range [%d-%d] begin to compute %n",
Thread.currentThread().getName(), lo, hi);
long result = 0;
if (hi - lo <= SEQUENTIAL_CUTOFF) {
for (int i = lo; i < hi; i++)
result += arr[i];
System.out.format("%s range [%d-%d] begin to finished %n",
Thread.currentThread().getName(), lo, hi);
}
else {
RecursiveSumTask left = new RecursiveSumTask(executorService, arr, lo, (hi + lo) / 2);
RecursiveSumTask right = new RecursiveSumTask(executorService, arr, (hi + lo) / 2, hi);
Future<Long> lr = executorService.submit(left);
Future<Long> rr = executorService.submit(right);
result = lr.get() + rr.get();
System.out.format("%s range [%d-%d] finished to compute %n",
Thread.currentThread().getName(), lo, hi);
}
return result;
}
Fork/Join并行处理框架
Java 1.7 引入了一种新的并发框架—— Fork/Join Framework
ForkJoinPool 框架主要类:
ForkJoinPool 实现ForkJoin的线程池 - ThreadPool
ForkJoinTask 一个描述ForkJoin的抽象类 Runnable/Callable
String keyPreFix = "foe:test:liuli";
Map<String, String> map = aliYunRedisService.hgetAll(keyPreFix);
List<String> keyList = new ArrayList<>();
for (String key : map.keySet()) {
keyList.add(map.get(key));
}
//分治
FockJoinTaskService fockJoinTest = new FockJoinTaskService(keyList,0,keyList.size(),aliYunRedisService);
ForkJoinPool forkJoinPool = new ForkJoinPool();
Future<List<QuestionSeriesUserInfoVo>> result = forkJoinPool.submit(fockJoinTest);
/**分治任务*/
public class FockJoinTaskService extends RecursiveTask<List<QuestionSeriesUserInfoVo>> {
AliYunRedisService aliYunRedisService;
List<String> keyList;
private static final int THREAD_HOLD = 500;
private int start;
private int end;
public FockJoinTaskService(List<String> keyList, int start, int end, AliYunRedisService aliYunRedisService) {
this.start = start;
this.end = end;
this.keyList = keyList;
this.aliYunRedisService =aliYunRedisService;
}
@Override
protected List<QuestionSeriesUserInfoVo> compute() {
List<QuestionSeriesUserInfoVo> testBeanList = new ArrayList<>();
boolean canCompute = (end - start) <= THREAD_HOLD;
if(canCompute){
for(int i=start ;i< end ;i++){
QuestionSeriesUserInfoVo questionSeriesUserInfoVo = new QuestionSeriesUserInfoVo();
String keyInfo = keyList.get(i);
if (StringUtils.isNotBlank(keyInfo)){
String keyInfoValue = aliYunRedisService.getAsString(keyInfo);
if (StringUtils.isNotBlank(keyInfo)){
questionSeriesUserInfoVo = JSONObject.parseObject(keyInfoValue,QuestionSeriesUserInfoVo.class);
testBeanList.add(questionSeriesUserInfoVo);
}
}
}
}else{
int middle = (start + end) / 2;
FockJoinTaskService left = new FockJoinTaskService(keyList,start,middle,aliYunRedisService);
FockJoinTaskService right = new FockJoinTaskService(keyList,middle,end,aliYunRedisService);
//执行子任务
left.fork();
right.fork();
//获取子任务结果
List<QuestionSeriesUserInfoVo> lResult = left.join();
List<QuestionSeriesUserInfoVo> rResult = right.join();
testBeanList.addAll(lResult);
testBeanList.addAll(rResult);
}
return testBeanList;
}
}