FutureTask与Fork/Join
在学习多线程的过程中,我们形成了一种思维习惯。那就是对于某个耗时操作不再做同步操作,让他分裂成一个线程之后执行下一步,而线程执行耗时操作。并且我们希望在我们需要它返回的时候再去调用它的结果集。好比我们把米饭和水放进了电饭煲,转头就去炒菜了,等到菜完成之后,转头去查看饭是否完成。多线程造成了并行计算的现象,有时候它们是真的多核计算而有时候只是单核的切换。
FutureTask表示的是一种,异步操作的典范。我提交了任务,在未来我要拿到结果。
考虑一种简单的场景,A问B一个问题,B一时回答不了,B要去考虑一段时间,等到有结果了,再告诉A。
这时,我们需要类A,类B。
package Future; //调用端
public class CallA implements CallBack{
private CallB b;
public CallA(CallB b){
this.b = b;
} public void submitProblem(String problem){
System.out.println("a 提交问题:"+problem);
new Thread(){
public void run(){
b.execute(CallA.this, problem);
}
}.start();
System.out.println("a 提交问题完毕");
} @Override
public void result(String result) {
System.out.println(result);
} }
package Future; //执行处理
public class CallB {
public void execute(CallBack callBack,String problem){
System.out.println("接受问题:"+problem);
System.out.println("开始处理");
try{
Thread.sleep(2000);
}catch (Exception e) {
e.printStackTrace();
}
callBack.result("问题处理结果:abcdefg...");
}
}
类的结构是,A中保留它作用对象B的一个引用,在触发询问问题的时候,A向B提交了一个方法调用,并且同时开启了一个线程,这是它不阻塞的原因。
为“提问题”做一个面向对象的接口。
//回调接口
public interface CallBack {
public void result(String result);
}
他们执行的主流程,十分简单。
public class Main {
public static void main(String[] args) {
CallB b = new CallB();
CallA a = new CallA(b);
a.submitProblem("英文字母");
}
}
熟悉了这个过程,JDK提供了FutureTask的接口。
package Future;
import java.util.concurrent.Callable;
public class RealData implements Callable<String>{
private String data;
public RealData(String data){
this.data = data;
}
@Override
public String call() throws Exception {
StringBuffer sb = new StringBuffer();
for(int i=0;i<10;i++){
sb.append(data);
try{
Thread.sleep(1500);
}catch (Exception e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
实现这个Callable接口,重写call方法,在未来调用get的时候将返回运算结果。
package Future; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask; //jdk future框架
public class FutureMain {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<String> future = new FutureTask<String>(new RealData("a"));
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(future);
System.out.println("请求完毕");
try{
Thread.sleep(1000);
}catch (Exception e) {
}
System.out.println("future task 返回:"+future.get());
}
}
多线程的优势体现在并行计算中,虽然某大佬说研究并行计算是在浪费时间,但是作为一种由多线程产生的技术来说,先了解一下特点。
JDK为我们提供了一套Join/Fork框架,考虑下面这个例子。
package ForkAndJoin;
import java.util.concurrent.RecursiveAction;
public class PrintTask extends RecursiveAction{
private final int Max = 50;
private int start;
private int end;
public PrintTask(int start,int end){
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if((end - start)<Max){
for(int i=start;i<end;i++){
System.out.println("当前线程:"+Thread.currentThread().getName()+" i :"+i);
}
}else{
int middle = (start+end)/2;
PrintTask left = new PrintTask(start, middle);
PrintTask right = new PrintTask(middle, end);
left.fork();
right.fork();
}
}
}
package ForkAndJoin; import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit; public class ForkJoinPoolTest {
public static void main(String[] args) throws InterruptedException {
ForkJoinPool forkJoin = new ForkJoinPool();
forkJoin.submit(new PrintTask(0,200));
forkJoin.awaitTermination(2, TimeUnit.SECONDS);
forkJoin.shutdown();
}
}
在compute方法中写主要的任务处理,这是一个并行计算的小例子。
J/F的模式很像map-reduce模式,将任务分小,然后各个处理。
FutureTask与Fork/Join的更多相关文章
- 一文带你了解J.U.C的FutureTask、Fork/Join框架和BlockingQueue
摘要: J.U.C是Java并发编程中非常重要的工具包,今天,我们就来着重讲讲J.U.C里面的FutureTask.Fork/Join框架和BlockingQueue. 本文分享自华为云社区<[ ...
- FutureTask、Fork/Join、 BlockingQueue
我们之前学习创建线程有Thread和Runnable两种方式,但是两种方式都无法获得执行的结果. 而Callable和Future在任务完成后得到结果. Future是一个接口,表示一个任务的周期 ...
- 九 fork/join CompletableFuture
1: Fork/join fork/join: fork是分叉的意思, join是合并的意思. Fork/Join框架:是JAVA7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务 ...
- JAVA中的Fork/Join框架
看了下Java Tutorials中的fork/join章节,整理下. 什么是fork/join框架 fork/join框架是ExecutorService接口的一个实现,可以帮助开发人员充分利用多核 ...
- JAVA并行框架:Fork/Join
一.背景 虽然目前处理器核心数已经发展到很大数目,但是按任务并发处理并不能完全充分的利用处理器资源,因为一般的应用程序没有那么多的并发处理任务.基于这种现状,考虑把一个任务拆分成多个单元,每个单元分别 ...
- 聊聊并发(八)——Fork/Join框架介绍
作者 方腾飞 发布于 2013年12月23日 | 被首富的“一个亿”刷屏?不如定个小目标,先把握住QCon上海的优惠吧!2 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 ...
- fork/join使用示例
fork/join框架是用多线程的方式实现分治法来解决问题.fork指的是将问题不断地缩小规模,join是指根据子问题的计算结果,得出更高层次的结果. fork/join框架的使用有一定的约束条件: ...
- Java Concurrency - Fork/Join Framework
Normally, when you implement a simple, concurrent Java application, you implement some Runnable obje ...
- Java 7 Fork/Join 并行计算框架概览
应用程序并行计算遇到的问题 当硬件处理能力不能按摩尔定律垂直发展的时候,选择了水平发展.多核处理器已广泛应用,未来处理器的核心数将进一步发布,甚至达到上百上千的数量.而现在 很多的应用程序在运行在多核 ...
随机推荐
- webkit com wrapper 推荐!
https://groups.google.com/forum/#!topic/microsoft.public.vb.general.discussion/ZaFY95aDZoY http://ww ...
- 安装scrapy解决的坑
在windows下: pip install scrapy 最后一步报错: 本来以为是缺少 Microsoft Visual C++ 14.0 这个库,一看下载需要400多M,算了再看下报错... 感 ...
- [Selenium] Java代码获取屏幕分辨率
import java.awt.Dimension; import java.awt.GraphicsEnvironment; import java.awt.Insets; import java. ...
- Mybatis之整体描述
Mybatis在我看来最大的用处就是封装了jdbc,设置参数操作和获取解析结果集.同时控制了数据库链接等操作,大部分采用了反射来映射javabean对象来进行数据库操作. 1.接下来先整体介绍下主要的 ...
- AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔)(转)
出处:http://www.bubuko.com/infodetail-827612.html AspNet.WebAPI.OData.ODataPQ 这是针对 Asp.net WebAPI ODat ...
- 百度地图api描绘车辆历史轨迹图
最近公司在做项目需需求:车辆定位后在地图显示历史轨迹的功能 一开始使用了google的地图api,但是发现会一直关闭,索性支持下国产,使用了百度地图api search方法把两个点连接成线后,会出现起 ...
- 使用 log4j 打印日志
开发阶段:发现程序的问题,排错 产品阶段:记录程序运行的状况 Maven中配置依赖 通过配置文件输出日志的格式,输送的位置等 一.入门实例 1.新建一个JAva工程,导入包log4j-1.2.17.j ...
- Websocket出现的错误
前端使用sockjs,后台使用spring的websocket框架 结果在一个网络较慢的地方,发现tomcat报错信息: Oct 28, 2015 10:10:43 AM org.apache.cat ...
- [leetcode] 13. Remove Duplicates from Sorted List
这个题目其实不难的,主要是我C++的水平太差了,链表那里绊了好久,但是又不像用python,所以还是强行上了. 题目如下: Given a sorted linked list, delete all ...
- Sharepoint安装的几处注意事项
0.sharepoint自带组件安装,无需另下载安装 1.必须安装域(不安装会提示sharepoint 指定的用户是本地账户) 2.域安装后需要在sharepoint设置的数据库账号具有域权限及高级权 ...