Future模式

Future模式

Future模式是多线程开发中的一种常见的设计模式,核心思想异步调用,让串行化的问题变得并行处理节省时间。当程序执行一个任务时,这个任务可能执行的很慢,它不可能立即返回结果,但可以返回一个契约,因此我们可以在该任务执行的时候,再去执行其它任务,最终用该契约获取结果。

举个例子:在网上买了一部手机,手机三天后才会到货,但会马上产生一个订单,这个订单就是上述所提到的契约,然后我们不用一直干等手机的到来,完全可以去忙别的事,当快递到来的时候,订单核对一下,然后就获得了最终结果。

JDK中的Future模式

在这里插入图片描述

Future接口类似于之前的契约,根据Future对象调用get方法最终获取到结果。FutureTask接口实现Callable接口对象到Runnable接口对象的过渡,其内部有一个Sync内部类,里面做一些实质性的工作,但最终会交由Callable接口完成,Callable接口的call方法返回最终结果。

简单使用
  • get方法
package com.github.excelent01;

import java.util.concurrent.*;

/**
 * @auther plg
 * @date 2019/5/17 16:54
 */
public class TestFuture {
    public static void main(String[] args) {
        ExecutorService service = Executors.newSingleThreadExecutor();
        Future<Integer> future =  service.submit(()->{
            TimeUnit.SECONDS.sleep(10); // 模拟延时
            return 10;
        });
        //==============================
        System.out.println("do other works.");
        //==============================
       
        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        service.shutdown();

    }
}

Future的get()方法会阻塞调用它的线程,直至取得返回结果,该方法会抛出一个中断异常,这个中断异常是中断调用get方法的线程时所引起的。与执行call方法的线程无关。其中get方法有一个重载即等待一定的时间,超出时间后就不等了,会响应一个异常,然后退出。

其它方法
  • boolean cancel(boolean mayInterruptIfRunning);
    取消任务,取消成功返回true,否则返回false。参数表示是否运行取消任务,正在执行且没有执行完的任务,都可以取消掉,若任务已经执行完毕,则不可以取消掉。任务没执行前不论参数是true或者false最终都返回true。
  • boolean isCancelled();
    判断任务是否已经取消
  • boolean isDone();
    判断任务是否已经完成
通过煮茶过程练习使用Future模式

在这里插入图片描述
因为烧水要花费15min,因此没有必要白白干等,浪费时间,在这个时间段内,可以去完成准备茶具的一些工作,等茶具准备好之后,就静等水烧开了。因此这是一个典型的依靠Future模式来解决的问题。

代码实现:
package Future;

import java.util.Scanner;
import java.util.concurrent.*;

/**
 * @auther plg
 * @date 2019/5/17 17:54
 */
public class TeaTest2 {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        BoilWater boilWater = new BoilWater();
        FutureTask<String> futureTask1 = new FutureTask<>(boilWater);
        ReadyTeaSet readyTeaSet = new ReadyTeaSet(futureTask1);
        FutureTask<String> futureTask2 = new FutureTask<>(readyTeaSet);
        new Thread(futureTask1).start();
        Thread.sleep(2000);
        new Thread(futureTask2).start();
        System.out.println(futureTask2.get());

    }
}
// T1 线程
class  BoilWater implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("T1: 洗水壶");
        Thread.sleep(1000);
        System.out.println("T1: 烧水");
        Thread.sleep(10000);
        return "T1: 水烧开了。";
    }
}
// T2 线程ReadyTeaSet
class ReadyTeaSet implements Callable<String>{
    private FutureTask<String> futureTask = null;
    public ReadyTeaSet(FutureTask<String> futureTask) {
        this.futureTask = futureTask;
    }

    @Override
    public String call() throws Exception {
        System.out.println("T2: 洗水杯");
        Thread.sleep(1000);
        System.out.println("T2: 洗茶壶");
        Thread.sleep(2000);
        System.out.println("T2: 取茶叶");
        Thread.sleep(1000);
        System.out.println("T2: 等着水烧开。");
        System.out.println(futureTask.get());
        return "一壶好茶.";
    }
}
运行结果:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值