abase

多线程高并发编程(8) -- Fork/Join源码分析

社会主义新天地 提交于 2020-08-11 02:14:50
一.概念    Fork/Join就是将一个大任务分解(fork)成许多个独立的小任务,然后多线程并行去处理这些小任务,每个小任务处理完得到结果再进行合并(join)得到最终的结果。    流程:任务继承RecursiveTask,重写compute方法,使用ForkJoinPool的submit提交任务,任务在某个线程中运行,工作任务中的compute方法的代码开始对任务进行分析,如果符合条件就进行任务拆分,拆分成多个子任务,每个子任务进行数据的计算或操作,得到结果返回给上一层任务开启线程进行合并,最终通过get获取整体处理结果。【 只能将任务1个切分为两个,不能切分为3个或其他数量 】 ForkJoinTask:代表fork/join里面的任务类型,一般用它的两个子类RecursiveTask(任务有返回值)和RecursiveAction(任务没有返回值),任务的处理逻辑包括任务的切分都是在重写compute方法里面进行处理。 只有ForkJoinTask任务可以被拆分运行和合并运行。 【 可查看上篇Future源码分析的类图结构 】【ForkJoinTask使用了模板模式进行设计,将ForkJoinTask的执行相关代码进行隐藏,通过提供抽象类(即子类RecursiveTask、RecursiveAction)暴露用户的实际业务处理。】 RecursiveTask

fork/join框架引发的思考

走远了吗. 提交于 2020-04-14 23:46:01
【推荐阅读】微服务还能火多久?>>> fork/join框架小demo /** * @Description:jork/join框架demo * @Author :YanDepeng * @Date :Created in 2020/4/14 17:07 * @Version : */ public class MyCountTask extends RecursiveTask { // 阈值 private static final int THRESHOLD = 2; private int start; private int end; public MyCountTask(){} public MyCountTask(int start, int end) { this.start = start; this.end = end; } @Override protected Integer compute() { int sum = 0; // 若任务足够小就执行任务,不在分割 int result; boolean canCompute = (end - start) <= THRESHOLD; if(canCompute) { sum += sum(start, end); } else { // 如果任务大于阈值,就分割未两个任务计算 int middle =

并发处理笔记:使用并发工具类库,就安全了吗?

泄露秘密 提交于 2020-04-05 17:52:18
没有意识到线程重用导致用户信息错乱的bug 我们知道,ThreadLocal适用于变量在线程间隔离,而在方法和类间共享的场景. 如果信息获取比较昂贵(比如从数据库中查询用户信息),那么在ThreadLocal中缓存数据是比较合适的做法.那什么时候会出现用户信息错乱的bug呢? 来看一个例子,使用spring boot创建一个web应用程序,使用threadlocal存放一个integer的值表示用户id,最后输出两次获取的值和线程名称. private ThreadLocal<Integer> currentUser = ThreadLocal.withInitial(() -> null); @GetMapping("wrong") pubilc Map wrong(@RequestParam("userId") Integer userId) { String before = Thread.currentThread().getName() + ":" + currentUser.get(); currentUser.set(userId); String after = Thread.currentThread().getName() + ":" + currentUser.get(); Map result = new HashMap(); result.put(