原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871099.html

Java线程--ForkJoinPool使用

简单解释下:

  Fork是执行的意思, Join是等待的意思, 结合使用就是先用Fork来执行子任务, 然后再用Join等待子任务全部执行完毕之后再统一处理或者返回 .

public static void main(String[] args) throws InterruptedException, ExecutionException {
/**
* 多线程框架
*/
Executor executor = null;
/**
* Executor 的子接口
*/
ExecutorService service = null;
/**
* ExecutorService 的抽象子类
*/
AbstractExecutorService service1 = null;
/**
* AbstractExecutorService 的子类
* 执行由一个大任务拆分成的多个小任务
* 完成一个任务的分段执行, 最后再统一处理
* 配合 ForkJoinTask 使用
*/
ForkJoinPool xxxx = new ForkJoinPool(); /**
* 异步计算返回的结果
*/
Future future = null;
/**
* Future的抽象子类
*/
ForkJoinTask forkJoinTask = null;
/**
* 没有返回值, ForkJoinTask的抽象子类
*/
RecursiveAction recursiveAction = null;
/**
* 有返回值, ForkJoinTask的抽象子类
*/
RecursiveTask recursiveTask = null; /**
* 来 300 个打印的任务
*/
PrintTasks printTasks = new PrintTasks(0, 200);
/**
* 来一个任务存储器
*/
ForkJoinPool forkJoinPool = new ForkJoinPool();
/**
* 提交任务
*/
forkJoinPool.submit(printTasks);
/**
* 等待所有任务完成
*/
forkJoinPool.awaitTermination(20, TimeUnit.SECONDS);
forkJoinPool.shutdown(); int[] intArr = new int[100];
Random random = new Random();
int total = 0;
int len = intArr.length;
for (int i = 0; i < len ; i++) {
int tmp = random.nextInt(5);
total += (intArr[i] = tmp);
}
System.out.println("初始化时的数组总和 : " + total);
SumTask sumTask = new SumTask(intArr, 0, len);
/**
* 通用池
*/
ForkJoinPool pool = new ForkJoinPool(8);
Future<Integer> future1 = pool.invoke(sumTask);
System.out.println("任务执行结果: " + future1.get());
pool.shutdown();
}
/**
* 继承 RecursiveAction 来实现任务可分解
*/
class PrintTasks extends RecursiveAction { private static final int THRESHOLD = 20; // 设置一个最多打印的数
private int start;
private int end; public PrintTasks(int start, int end) {
super();
this.start = start;
this.end = end;
} @Override
protected void compute() {
/**
* 进行小任务划分
*/
if (end - start < THRESHOLD) {
for(int i=start; i<end ; i++){
System.out.println(Thread.currentThread().getName()+"的i : "+i);
}
} else {
/**
* 二分法, 直到任务的规模小于规定的规模为止
*/
int middle =(start+end)/2;
PrintTasks left = new PrintTasks(start, middle);
PrintTasks right = new PrintTasks(middle, end);
/**
* fork() 就是执行的意思left.fork();right.fork();
* 这里并行执行以下
*/
invokeAll(left, right); }
}
}
/**
* 统计总数的任务
*/
class SumTask extends RecursiveTask<Integer> { /**
* 每个小任务 最多只累加5个数
*/
private static final int THRESHOLD = 5;
/**
* 数据的数组
*/
private int arry[];
private int start;
private int end; public SumTask(int[] arry, int start, int end) {
super();
this.arry = arry;
this.start = start;
this.end = end;
} /**
* 类种是什么类型的值就返回什么类型的值
* @return
*/
@Override
protected Integer compute() {
int sum =0;
/**
* 当end与start之间的差小于设定任务数量时,才开始进行实际的累加
*/
if(end - start <THRESHOLD){
for(int i= start;i<end;i++){
sum += arry[i];
}
return sum;
}else {
/**
* 任务数量超过规定执行数量时 , 进行二分法拆分
*/
int middle = (start+ end)/2;
SumTask small = new SumTask(arry, start, middle);
SumTask big = new SumTask(arry, middle, end);
/**
* 执行任务 small.fork(); big.fork();
*/
invokeAll(small, big); /**
* 把各个小任务累加的结果合并起来并且返回
* join() 会等待子任务执行完并得到其结果
*/
return small.join()+big.join();
}
}
}

打印结果如下:

ForkJoinPool-2-worker-1的i : 187
ForkJoinPool-2-worker-2的i : 87
ForkJoinPool-2-worker-2的i : 88
ForkJoinPool-2-worker-2的i : 89
ForkJoinPool-2-worker-2的i : 90
ForkJoinPool-2-worker-2的i : 91
ForkJoinPool-2-worker-2的i : 92
ForkJoinPool-2-worker-2的i : 93
ForkJoinPool-2-worker-2的i : 94
ForkJoinPool-2-worker-2的i : 95
ForkJoinPool-2-worker-2的i : 96
ForkJoinPool-2-worker-2的i : 97
ForkJoinPool-2-worker-2的i : 98
ForkJoinPool-2-worker-2的i : 99
ForkJoinPool-2-worker-2的i : 75
ForkJoinPool-2-worker-2的i : 76
ForkJoinPool-2-worker-2的i : 77
ForkJoinPool-2-worker-2的i : 78
ForkJoinPool-2-worker-2的i : 79
ForkJoinPool-2-worker-2的i : 80
ForkJoinPool-2-worker-2的i : 81
ForkJoinPool-2-worker-2的i : 82
ForkJoinPool-2-worker-2的i : 83
ForkJoinPool-2-worker-2的i : 84
ForkJoinPool-2-worker-2的i : 85
ForkJoinPool-2-worker-2的i : 86
ForkJoinPool-2-worker-2的i : 62
ForkJoinPool-2-worker-2的i : 63
ForkJoinPool-2-worker-2的i : 64
ForkJoinPool-2-worker-2的i : 65
ForkJoinPool-2-worker-2的i : 66
ForkJoinPool-2-worker-2的i : 67
ForkJoinPool-2-worker-2的i : 68
ForkJoinPool-2-worker-2的i : 69
ForkJoinPool-2-worker-2的i : 70
ForkJoinPool-2-worker-2的i : 71
ForkJoinPool-2-worker-2的i : 72
ForkJoinPool-2-worker-2的i : 73
ForkJoinPool-2-worker-2的i : 74
ForkJoinPool-2-worker-2的i : 50
ForkJoinPool-2-worker-2的i : 51
ForkJoinPool-2-worker-2的i : 52
ForkJoinPool-2-worker-2的i : 53
ForkJoinPool-2-worker-2的i : 54
ForkJoinPool-2-worker-2的i : 55
ForkJoinPool-2-worker-1的i : 188
ForkJoinPool-2-worker-1的i : 189
ForkJoinPool-2-worker-1的i : 190
ForkJoinPool-2-worker-1的i : 191
ForkJoinPool-2-worker-1的i : 192
ForkJoinPool-2-worker-1的i : 193
ForkJoinPool-2-worker-1的i : 194
ForkJoinPool-2-worker-1的i : 195
ForkJoinPool-2-worker-1的i : 196
ForkJoinPool-2-worker-1的i : 197
ForkJoinPool-2-worker-1的i : 198
ForkJoinPool-2-worker-1的i : 199
ForkJoinPool-2-worker-1的i : 175
ForkJoinPool-2-worker-1的i : 176
ForkJoinPool-2-worker-1的i : 177
ForkJoinPool-2-worker-1的i : 178
ForkJoinPool-2-worker-1的i : 179
ForkJoinPool-2-worker-1的i : 180
ForkJoinPool-2-worker-1的i : 181
ForkJoinPool-2-worker-1的i : 182
ForkJoinPool-2-worker-1的i : 183
ForkJoinPool-2-worker-1的i : 184
ForkJoinPool-2-worker-1的i : 185
ForkJoinPool-2-worker-1的i : 186
ForkJoinPool-2-worker-1的i : 162
ForkJoinPool-2-worker-1的i : 163
ForkJoinPool-2-worker-1的i : 164
ForkJoinPool-2-worker-1的i : 165
ForkJoinPool-2-worker-1的i : 166
ForkJoinPool-2-worker-1的i : 167
ForkJoinPool-2-worker-1的i : 168
ForkJoinPool-2-worker-1的i : 169
ForkJoinPool-2-worker-1的i : 170
ForkJoinPool-2-worker-1的i : 171
ForkJoinPool-2-worker-1的i : 172
ForkJoinPool-2-worker-1的i : 173
ForkJoinPool-2-worker-1的i : 174
ForkJoinPool-2-worker-1的i : 150
ForkJoinPool-2-worker-1的i : 151
ForkJoinPool-2-worker-1的i : 152
ForkJoinPool-2-worker-1的i : 153
ForkJoinPool-2-worker-1的i : 154
ForkJoinPool-2-worker-2的i : 56
ForkJoinPool-2-worker-2的i : 57
ForkJoinPool-2-worker-2的i : 58
ForkJoinPool-2-worker-2的i : 59
ForkJoinPool-2-worker-2的i : 60
ForkJoinPool-2-worker-2的i : 61
ForkJoinPool-2-worker-2的i : 37
ForkJoinPool-2-worker-2的i : 38
ForkJoinPool-2-worker-2的i : 39
ForkJoinPool-2-worker-2的i : 40
ForkJoinPool-2-worker-2的i : 41
ForkJoinPool-2-worker-2的i : 42
ForkJoinPool-2-worker-2的i : 43
ForkJoinPool-2-worker-2的i : 44
ForkJoinPool-2-worker-2的i : 45
ForkJoinPool-2-worker-2的i : 46
ForkJoinPool-2-worker-2的i : 47
ForkJoinPool-2-worker-2的i : 48
ForkJoinPool-2-worker-2的i : 49
ForkJoinPool-2-worker-2的i : 25
ForkJoinPool-2-worker-2的i : 26
ForkJoinPool-2-worker-2的i : 27
ForkJoinPool-2-worker-2的i : 28
ForkJoinPool-2-worker-2的i : 29
ForkJoinPool-2-worker-2的i : 30
ForkJoinPool-2-worker-2的i : 31
ForkJoinPool-2-worker-2的i : 32
ForkJoinPool-2-worker-2的i : 33
ForkJoinPool-2-worker-2的i : 34
ForkJoinPool-2-worker-2的i : 35
ForkJoinPool-2-worker-2的i : 36
ForkJoinPool-2-worker-2的i : 12
ForkJoinPool-2-worker-2的i : 13
ForkJoinPool-2-worker-2的i : 14
ForkJoinPool-2-worker-2的i : 15
ForkJoinPool-2-worker-2的i : 16
ForkJoinPool-2-worker-2的i : 17
ForkJoinPool-2-worker-2的i : 18
ForkJoinPool-2-worker-2的i : 19
ForkJoinPool-2-worker-2的i : 20
ForkJoinPool-2-worker-2的i : 21
ForkJoinPool-2-worker-2的i : 22
ForkJoinPool-2-worker-2的i : 23
ForkJoinPool-2-worker-2的i : 24
ForkJoinPool-2-worker-2的i : 0
ForkJoinPool-2-worker-2的i : 1
ForkJoinPool-2-worker-2的i : 2
ForkJoinPool-2-worker-2的i : 3
ForkJoinPool-2-worker-2的i : 4
ForkJoinPool-2-worker-2的i : 5
ForkJoinPool-2-worker-2的i : 6
ForkJoinPool-2-worker-2的i : 7
ForkJoinPool-2-worker-2的i : 8
ForkJoinPool-2-worker-2的i : 9
ForkJoinPool-2-worker-2的i : 10
ForkJoinPool-2-worker-2的i : 11
ForkJoinPool-2-worker-2的i : 137
ForkJoinPool-2-worker-2的i : 138
ForkJoinPool-2-worker-2的i : 139
ForkJoinPool-2-worker-2的i : 140
ForkJoinPool-2-worker-2的i : 141
ForkJoinPool-2-worker-2的i : 142
ForkJoinPool-2-worker-2的i : 143
ForkJoinPool-2-worker-2的i : 144
ForkJoinPool-2-worker-2的i : 145
ForkJoinPool-2-worker-2的i : 146
ForkJoinPool-2-worker-2的i : 147
ForkJoinPool-2-worker-2的i : 148
ForkJoinPool-2-worker-2的i : 149
ForkJoinPool-2-worker-2的i : 125
ForkJoinPool-2-worker-2的i : 126
ForkJoinPool-2-worker-2的i : 127
ForkJoinPool-2-worker-2的i : 128
ForkJoinPool-2-worker-2的i : 129
ForkJoinPool-2-worker-2的i : 130
ForkJoinPool-2-worker-2的i : 131
ForkJoinPool-2-worker-2的i : 132
ForkJoinPool-2-worker-2的i : 133
ForkJoinPool-2-worker-2的i : 134
ForkJoinPool-2-worker-2的i : 135
ForkJoinPool-2-worker-2的i : 136
ForkJoinPool-2-worker-2的i : 112
ForkJoinPool-2-worker-2的i : 113
ForkJoinPool-2-worker-2的i : 114
ForkJoinPool-2-worker-2的i : 115
ForkJoinPool-2-worker-2的i : 116
ForkJoinPool-2-worker-2的i : 117
ForkJoinPool-2-worker-2的i : 118
ForkJoinPool-2-worker-2的i : 119
ForkJoinPool-2-worker-2的i : 120
ForkJoinPool-2-worker-2的i : 121
ForkJoinPool-2-worker-2的i : 122
ForkJoinPool-2-worker-2的i : 123
ForkJoinPool-2-worker-2的i : 124
ForkJoinPool-2-worker-2的i : 100
ForkJoinPool-2-worker-2的i : 101
ForkJoinPool-2-worker-2的i : 102
ForkJoinPool-2-worker-2的i : 103
ForkJoinPool-2-worker-2的i : 104
ForkJoinPool-2-worker-2的i : 105
ForkJoinPool-2-worker-2的i : 106
ForkJoinPool-2-worker-2的i : 107
ForkJoinPool-2-worker-2的i : 108
ForkJoinPool-2-worker-2的i : 109
ForkJoinPool-2-worker-2的i : 110
ForkJoinPool-2-worker-2的i : 111
ForkJoinPool-2-worker-1的i : 155
ForkJoinPool-2-worker-1的i : 156
ForkJoinPool-2-worker-1的i : 157
ForkJoinPool-2-worker-1的i : 158
ForkJoinPool-2-worker-1的i : 159
ForkJoinPool-2-worker-1的i : 160
ForkJoinPool-2-worker-1的i : 161
初始化时的数组总和 : 204
任务执行结果: 204

执行结果

Java线程--ForkJoinPool使用的更多相关文章

  1. 使用Java 线程池的利弊及JDK自带六种创建线程池的方法

    1. 为什么使用线程池 诸如 Web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过网络协 ...

  2. Java线程池—ThreadPool简介

    一.Java线程池类/接口关系图及作用 Executor接口:只有一个方法execute(Runnable command),用来执行用户的任务线程. ExecutorService接口:继承自Exe ...

  3. Java线程池 Executor框架概述

    线程池的意义 循环利用线程资源,避免重复创建和销毁线程 线程池的任务是异步执行的,只要提交完成就能快速返回,可以提高应用响应性 Java线程池还有一个很重要的意义:Java线程池就是JDK 5 推出的 ...

  4. Netty核心概念(7)之Java线程池

    1.前言 本章本来要讲解Netty的线程模型的,但是由于其是基于Java线程池设计而封装的,所以我们先详细学习一下Java中的线程池的设计.之前也说过Netty5被放弃的原因之一就是forkjoin结 ...

  5. java线程高并发编程

    java线程具体解释及高并发编程庖丁解牛 线程概述: 祖宗: 说起java高并发编程,就不得不提起一位老先生Doug Lea,这位老先生可不得了.看看百度百科对他的评价,一点也不为过: 假设IT的历史 ...

  6. Java线程池详解(二)

    一.前言 在总结了线程池的一些原理及实现细节之后,产出了一篇文章:Java线程池详解(一),后面的(一)是在本文出现之后加上的,而本文就成了(二).因为在写完第一篇关于java线程池的文章之后,越发觉 ...

  7. Java线程池原理解读

    引言 引用自<阿里巴巴JAVA开发手册> [强制]线程资源必须通过线程池提供,不允许在应用中自行显式创建线程. 说明:使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销 ...

  8. java线程池,工作窃取算法

    前言 在上一篇<java线程池,阿里为什么不允许使用Executors?>中我们谈及了线程池,同时又发现一个现象,当最大线程数还没有满的时候耗时的任务全部堆积给了单个线程, 代码如下: T ...

  9. 面试题-关于Java线程池一篇文章就够了

    在Java面试中,线程池相关知识,虽不能说是必问提,但出现的频次也是非常高的.同时又鉴于公众号"程序新视界"的读者后台留言让写一篇关于Java线程池的文章,于是就有本篇内容,本篇将 ...

随机推荐

  1. Java初学者作业——编写JAVA程序,在控制台输入一位学生的英语考试成绩,根据评测规则,输出对应的成绩等级。定义方法实现学生成绩的评测功能。

    返回本章节 返回作业目录 需求说明: 编写JAVA程序,在控制台输入一位学生的英语考试成绩,根据评测规则,输出对应的成绩等级.要求:定义方法实现学生成绩的评测功能. 学生的英语考试成绩进行评测,评测规 ...

  2. SpringBoot集成MyBatis-Plus框架

    1.说明 本文介绍Spring Boot集成MyBatis-Plus框架, 重点介绍需要注意的地方, 是SpringBoot集成MyBatis-Plus框架详细方法 这篇文章的脱水版, 主要是三个步骤 ...

  3. [学习笔记] RabbitMQ的安装使用

    安装 使用命令行安装,会自动管理依赖(推荐): choco install rabbitmq 安装包安装: 以管理员身份安装64位的 Erlang. 下载并安装 RabbitMQ 服务.下载地址. R ...

  4. .NetCore下构建自己的服务配置中心-手动造轮子

    本人主要利用IdentityServer4以及SignalR来实现,IdentityServer4作为认证,SignalR来交互配置,这里一些代码可能就是部分提出来,主要介绍实现原理及方法 实现配置中 ...

  5. Chrome - XPath Helper插件 使用手工拖拽方式无法正常安装的解决办法

    安装前准备: (1)下载 XPath Helper资源: 链接: https://pan.baidu.com/s/1yEnngIJz8fT9fNv3aHhs7w 提取码: afy3 (2)Chrome ...

  6. Vue系列教程(二)之Vue进阶

    一.Vue对象的操作 1. 可以通过一个Vue对象操作另一个Vue对象 var v1 = new Vue({ el: "#app1", data: {title:"hel ...

  7. Maven自定义jar包名

    一.默认命名 <finalName>${project.artifactId}-${project.version}</finalName> 二.自定义包名 <build ...

  8. c++智能指针的使用,shared_ptr,unique_ptr,weak_ptr

    c++智能指针的使用 官方参考 普通指针的烦恼:内存泄漏,多次释放,提前释放 智能指针 负责自动释放所指向的对象. 三种智能指针 shared_ptr,unique_ptr,weak_ptr: 将sh ...

  9. Linux基础之终端、控制台、tty、pty简介说明

    最近在搞Linux提权的时候,有时候su 用户名 登录的时候发现登录不了,因为tty终端,交互不了,所以我也来总结一下 一. 基本概念 1. ttytty(终端设备的统称):tty一词源于telety ...

  10. 联盛德 HLK-W806 (十三): 运行FatFs读写FAT和exFat格式的SD卡/TF卡

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...