任务类型
CPU密集型任务
也叫计算密集型任务,比如加密、解密、压缩、计算等一系列需要大量耗费 CPU 资源的任务。对于这样的任务最佳的线程数为 CPU 核心数的 1~2 倍。
IO密集型任务
比如数据库、文件的读写,网络通信等任务,这种任务的特点是并不会特别消耗 CPU 资源,但是 IO 操作很耗时,总体会占用比较多的时间。对于这种任务最大线程数一般会大于 CPU 核心数很多倍,因为 IO 读写速度相比于 CPU 的速度而言是比较慢的。
推荐的线程计算方法: 线程数 = CPU 核心数 *(1+平均等待时间/平均工作时间)
分治算法
分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。
分治算法的步骤:
- 分解:将要解决的问题划分成若干规模较小的同类问题
- 求解:当子问题划分得足够小时,用较简单的方法解决
- 合并:按原问题的要求,将子问题的解逐层合并构成原问题的解
Fork/Join介绍
是一种基于分治算法的,主要包含两部分,一部分是分治任务的线程池 ForkJoinPool,另一部分是分治任务 ForkJoinTask。ForkJoinPool允许其他线程向它提交任务,并根据设定将这些任务拆分为粒度更细的子任务,这些子任务将由ForkJoinPool内部的工作线程来并行执行,并且工作线程之间可以窃取彼此之间的任务。
ForkJoinPool最适合计算密集型任务,而且最好是非阻塞任务。ForkJoinPool是ThreadPoolExecutor线程池的一种补充,是对计算密集型场景的加强。
ForkJoinPool
ForkJoinPool 是用于执行 ForkJoinTask 任务的执行池,不再是传统执行池 Worker+Queue 的组合式,而是维护了一个队列数组 WorkQueue(数组)
//parallelism指定并行级别,ForkJoinPool将根据这个设定,决定工作线程的数量//默认是用CPU逻辑和核数来设置并行级别//factory:ForkJoinPool在创建线程时,会通过factory来创建// handler:指定异常处理器//asyncMode:设置队列的工作模式,asyncMode为true时,使用先进先出队列//asyncMode为false时则使用后进先出的模式public ForkJoinPool(int parallelism,ForkJoinWorkerThreadFactory factory,UncaughtExceptionHandler handler,boolean asyncMode) {this(checkParallelism(parallelism),checkFactory(factory),handler,asyncMode ? FIFO_QUEUE : LIFO_QUEUE,"ForkJoinPool-" + nextPoolId() + "-worker-");checkPermission();}
ForkJoinPool提交任务方式
提交异步执行execute
- execute类型的方法在提交任务后,不会返回结果。可以提交ForkJoinTask任务或者Runnable任务

等待并获取结果invoke
- invoke方法接受ForkJoinTask类型的任务,并在任务执行结束后,返回泛型结果
提交执行获取Future结果(submit)
- 在提交任务后,将返回ForkJoinTask类型的结果
