scheduleWithFixedDelay
是以任务执行结束的时间点作为计时的开始 。如下所示
文章插图
SingleThreadScheduledExecutor
- 它实际和
ScheduledThreadPool
线程池非常相似,它只是ScheduledThreadPool
的一个特例,内部只有一个线程,它只是将ScheduledThreadPool
的核心线程数设置为了 1 。如源码所示:
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));}
- 上面我们介绍了五种常见的线程池,对于这些线程池我们可以从核心线程数、最大线程数、存活时间三个维度进行一个简单的对比,有利于我们加深对这几种线程池的记忆 。
ForkJoinPool
这是一个在JDK7
引入的新新线程池,它的主要特点是可以充分利用多核CPU
, 可以把一个任务拆分为多个子任务,这些子任务放在不同的处理器上并行执行,当这些子任务执行结束后再把这些结果合并起来,这是一种分治思想 。ForkJoinPool
也正如它的名字一样,第一步进行Fork
拆分,第二步进行Join
合并,我们先来看一下它的类图结构
文章插图
ForkJoinPool
的使用也是通过调用submit(ForkJoinTask<T> task)
或invoke(ForkJoinTask<T> task)
方法来执行指定任务了 。其中任务的类型是ForkJoinTask
类,它代表的是一个可以合并的子任务,他本身是一个抽象类,同时还有两个常用的抽象子类RecursiveAction
和RecursiveTask
,其中RecursiveTask
表示的是有返回值类型的任务,而RecursiveAction
则表示无返回值的任务 。下面是它们的类图:
文章插图
- 下面我们通过一个简单的代码先来看一下如何使用
ForkJoinPool
线程池
/** * @url: i-code.online * @author: AnonyStar * @time: 2020/11/2 10:01 */public class ForkJoinApp1 {/**目标: 打印0-200以内的数字,进行分段每个间隔为10以上,测试forkjoin*/public static void main(String[] args) {// 创建线程池,ForkJoinPool joinPool = new ForkJoinPool();// 创建根任务SubTask subTask = new SubTask(0,200);// 提交任务joinPool.submit(subTask);//让线程阻塞等待所有任务完成 在进行关闭try {joinPool.awaitTermination(2, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();}joinPool.shutdown();}}classSubTask extends RecursiveAction {int startNum;int endNum;public SubTask(int startNum,int endNum){super();this.startNum = startNum;this.endNum = endNum;}@Overrideprotected void compute() {if (endNum - startNum < 10){// 如果分裂的两者差值小于10 则不再继续,直接打印System.out.println(Thread.currentThread().getName()+": [startNum:"+startNum+",endNum:"+endNum+"]");}else {// 取中间值int middle = (startNum + endNum) / 2;//创建两个子任务,以递归思想,SubTask subTask = new SubTask(startNum,middle);SubTask subTask1 = new SubTask(middle,endNum);//执行任务,fork() 表示异步的开始执行subTask.fork();subTask1.fork();}}}
结果:文章插图
- 从上面的案例我们可以看到我们,创建了很多个线程执行,因为我测试的电脑是12线程的,所以这里实际是创建了12个线程,也侧面说明了充分调用了每个处理的线程处理能力
- 上面案例其实我们发现很熟悉的味道,那就是以前接触过的递归思想,将上面的案例图像化如下,更直观的看到,
文章插图
- 上面的例子是无返回值的案例,下面我们来看一个典型的有返回值的案例,相信大家都听过及很熟悉斐波那契数列,这个数列有个特点就是最后一项的结果等于前两项的和,如:
0,1,1,2,3,5...f(n-2)+f(n-1)
推荐阅读
- python之最详细字符串篇
- 什么鱼凶猛 观赏鱼中最凶猛的鱼是哪种
- Spring Boot中一接多口实现
- 如何挑选三文鱼
- 如何挑选薄荷
- 如何挑选鲅鱼
- 北方茶市的重要参照,走进中国近海第茶―御海湾
- 生活中常见事物蕴含的道理 生活中的事物
- 烟雨江湖主线任务攻略 烟雨江湖中的支线任务攻略大全
- 龙井茶用中投法泡吗,想喝好的龙井茶