future java fork_FutureTask与Fork/Join

在学习多线程的过程中,我们形成了一种思维习惯。那就是对于某个耗时操作不再做同步操作,让他分裂成一个线程之后执行下一步,而线程执行耗时操作。并且我们希望在我们需要它返回的时候再去调用它的结果集。好比我们把米饭和水放进了电饭煲,转头就去炒菜了,等到菜完成之后,转头去查看饭是否完成。多线程造成了并行计算的现象,有时候它们是真的多核计算而有时候只是单核的切换。

FutureTask表示的是一种,异步操作的典范。我提交了任务,在未来我要拿到结果。

考虑一种简单的场景,A问B一个问题,B一时回答不了,B要去考虑一段时间,等到有结果了,再告诉A。

这时,我们需要类A,类B。

packageFuture;//调用端

public class CallA implementsCallBack{privateCallB b;publicCallA(CallB b){this.b =b;

}public voidsubmitProblem(String problem){

System.out.println("a 提交问题:"+problem);newThread(){public voidrun(){

b.execute(CallA.this, problem);

}

}.start();

System.out.println("a 提交问题完毕");

}

@Overridepublic voidresult(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 classMain {public static voidmain(String[] args) {

CallB b= newCallB();

CallA a= newCallA(b);

a.submitProblem("英文字母");

}

}

熟悉了这个过程,JDK提供了FutureTask的接口。

packageFuture;importjava.util.concurrent.Callable;public class RealData implements Callable{privateString data;publicRealData(String data){this.data =data;

}

@Overridepublic String call() throwsException {

StringBuffer sb= newStringBuffer();for(int i=0;i<10;i++){

sb.append(data);try{

Thread.sleep(1500);

}catch(Exception e) {

e.printStackTrace();

}

}returnsb.toString();

}

}

实现这个Callable接口,重写call方法,在未来调用get的时候将返回运算结果。

packageFuture;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.FutureTask;//jdk future框架

public classFutureMain {public static void main(String[] args) throwsInterruptedException, ExecutionException {

FutureTask future = new FutureTask(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框架,考虑下面这个例子。

packageForkAndJoin;importjava.util.concurrent.RecursiveAction;public class PrintTask extendsRecursiveAction{private final int Max = 50;private intstart;private intend;public PrintTask(int start,intend){this.start =start;this.end =end;

}

@Overrideprotected voidcompute() {if((end - start)

System.out.println("当前线程:"+Thread.currentThread().getName()+" i :"+i);

}

}else{int middle = (start+end)/2;

PrintTask left= newPrintTask(start, middle);

PrintTask right= newPrintTask(middle, end);

left.fork();

right.fork();

}

}

}

packageForkAndJoin;importjava.util.concurrent.ForkJoinPool;importjava.util.concurrent.TimeUnit;public classForkJoinPoolTest {public static void main(String[] args) throwsInterruptedException {

ForkJoinPool forkJoin= newForkJoinPool();

forkJoin.submit(new PrintTask(0,200));

forkJoin.awaitTermination(2, TimeUnit.SECONDS);

forkJoin.shutdown();

}

}

在compute方法中写主要的任务处理,这是一个并行计算的小例子。

J/F的模式很像map-reduce模式,将任务分小,然后各个处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值