Java--8--新特性--串并行流与ForkJoin框架

之前说的AQS,其实AQS的设计很难达到的高度,开发中常用的工具想出来,知道大家有这个需求,开发人员需求可以通过这种方式降低代码量,软件开发思维很重要,抽象的模板方法,模板方法的经典实现(AbstractOwnableSynchronizer),看一些源码,实现原理,还需要了解内部的原理,原理无非就是用到了park,unpark,lock,sync,逻辑其实不复杂,仔细看都可以看懂,关键抽象的思维真的很难理解透,看它的源码就是要理解,原来可以这么取抽象,大家中存在大量的重复的逻辑,这时候需要考虑能否将重复代码进行抽象,重复的代码逻辑,AQS身上类似的逻辑,是否可以抽象成,一个模板的方法,设计模式的提现。增删改查在很多框架里面也进行了抽象,逻辑是固定的,都可以进行抽象的。做成地图的方式学习他的思维很重要。

(一)ForkJoin

  • ① 介绍

从JDK1.7开始,Java提供Fork/Join框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任务,最终汇总每个小任务的结果得到这个大任务的结果。将一个复杂的计算,按照设定的阈值进行分解成多个计算,然后将各个计算结果进行汇总。相应的ForkJoin将复杂的计算当做一个任务。而分解的多个计算则是当做一个子任务。

  • ② 场景

ForkJoinPool 是 ExecutorService接口的实现,它专为可以递归分解成为小块的工作而设计,for/join框架将任务分配给线程池中的工作线程,充分利用多处理器的优势,提高程序性能。

使用fork join 的第一步是编写执行一部分工作的代码。将代码包装在ForkJoinTask子类中,通常是RecursiveTask(可以返回结果) 或 RecursiveAction。

  • ③ 实现思路
  1. 每个worker线程都维护一个任务队列,即ForkJoinWorkerThread中的任务队列。
  2. 任务队列是双向队列,这样可以同时实现LIFO和FIFO(First in, First out.先进先出。Last in, First out.后进先出)
  3. 子任务会被加入到原先任务所在worker线程的任务队列。
  4. Worker线程用LIFO的方法取出任务,后进队列的任务先取出来(子任务总是后加入队列,但是需要先执行)
  5. 当任务队列为空,会随机从其他的worker的队列中拿走一个任务执行(工作窃取:steal work)
  6. 如果一个worker线程遇到了join操作,而这个时候正在处理其他任务,会等到这个任务结束。否则直接返回。
  7. 如果一个worker线程窃取任务失败,它会用yield或者sleep之类的方法休息一会,再尝试(如果所有线程都是空闲状态,即没有任务运行,那么该线程也会进入阻塞状态等新任务的到来)
  • ⑤ 适用

适用尽可能少的线程池 - 在大多数情况下,最好的决定是为了每个应用程序或系统使用一个线程池,如果不需要特定调整,请使用默认的公共线程池,使用合理的阈值将ForkJoinTask拆分为子任务,避免ForkJoinTask中出现任何阻塞(调用接口,调用数据库)。

  • ⑥ 源码

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

// 分而治之的理念
public class ForkJoinDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 默认情况下,并行线程数量等于可用处理器的数量
        // ForkJoinPool与其他类型的ExecutorService的区别主要在于它使用了工作窃取:
        // 池中的所有线程都试图查找和执行提交给池的任务和/或其他活动任务创建的任务
        // (如果不存在工作,则最终阻塞等待工作)。
        ForkJoinPool forkJoinPool = new ForkJoinPool();

        RecursiveTask<String> recursiveTask = new RecursiveTask<String>() {
            @Override
            protected String compute() {
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(toString() + "" + Thread.currentThread());
                ForkJoinTask<String> newTask = this.fork();
                newTask.join();
                System.out.println("执行结束");
                return "";
            }
        };

        ForkJoinTask<String> submit = forkJoinPool.submit(recursiveTask);
        ForkJoinTask<String> submitx = forkJoinPool.submit(recursiveTask);
        System.out.println(submit.get());

        recursiveTask.join();
    }
}

PS:工作窃取带来的性能提升偏理论,API的复杂性较高,实际研发中可控性来说不如其他API。一般使用最多的就是做数据处理。接口和数据库尽量不要使用,线程如何堵塞了就尴尬了。吐槽下,从JDK1.8以后,JDK的源码越来越难度了,变量都是一个字母。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容