转多线程设计模式 - Future模式之JAVA原生实现

 在之前一篇博客中介绍了Future设计模式的设计思想以及具体实现,今天我们来讲一下使用JDK原生的包如何实现。

  JDK内置的Future主要使用到了Callable接口和FutureTask类。

  Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务。Callable接口的定义如下:

public interface Callable<V> {    /**     * Computes a result, or throws an exception if unable to do so.     *     * @return computed result     * @throws Exception if unable to compute a result     */    V call() throws Exception;}

  Callable的类型参数是返回值的类型。例如:

Callable<Integer>表示一个最终返回Integer对象的异步计算。

  Future保存异步计算的结果。实际应用中可以启动一个计算,将Future对象交给某个线程,然后执行其他操作。Future对象的所有者在结果计算好之后就可以获得它。Future接口具有下面的方法:

public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}

  第一个get方法的调用被阻塞,直到计算完成。如果在计算完成之前,第二个get方法的调用超时,抛出一个TimeoutException异常。如果运行该计算的线程被中断,两个方法都将抛出InterruptedException。如果计算已经完成,那么get方法立即返回。

  如果计算还在进行,isDone方法返回false;如果完成了,则返回true。

  可以用cancel方法取消该计算。如果计算还没有开始,它被取消且不再开始。如果计算处于运行之中,那么如果mayInterrupt参数为true,它就被中断。

  FutureTask包装器是一种非常便利的机制,同时实现了Future和Runnable接口。FutureTask有2个构造方法:

public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;       // ensure visibility of callable
}

  通常,我们会使用Callable示例构造一个FutureTask对象,并将它提交给线程池进行处理,下面我们将展示这个内置的Future模式的使用。

public class RealData implements Callable<String> {
    private String param;
    public RealData(String param){
        this.param = param;
    }
    @Override
    public String call() throws Exception {
        StringBuffer sb = new StringBuffer();
        for(int i = 0 ; i< 10 ;i++){
            sb.append(param);
            try {
                Thread.sleep(100);
            }catch (InterruptedException e){

            }
        }
        return sb.toString();
    }
}

  上述代码实现了Callable接口,它的Call方法会构造我们需要的真实数据并返回,当然这个过程比较缓慢,这里使用Thread.sleep()来模拟它:

public class FutureMain {
    public static void main(String[] args)
            throws ExecutionException, InterruptedException {
        //构造FutureTask
        FutureTask<String> futureTask = new FutureTask<String>(new RealData("xxx"));
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        //执行FutureTask,发送请求
        //在这里开启线程进行RealData的call()执行
        executorService.submit(futureTask);

        System.out.println("请求完毕。。。");
        try {
            //这里可以进行其他额外的操作,这里用sleep代替其他业务的处理
            Thread.sleep(200);
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
        //获取call()方法的返回值
        //如果此时call()方法没有执行完成,则依然会等待
        System.out.println("真实数据:"+futureTask.get());
    }
}

  上述代码就是使用Future模式的典型。构造FutureTask时使用Callable接口,告诉FutureTask我们需要的数据应该有返回值。然后将FutureTask提交给线程池,接下来我们不用关心数据是怎么产生的,可以去做其他的业务逻辑处理,然后在需要的时候调用FutureTask.get()得到实际的数据。

  Future模式在日常业务中处理复杂业务时会经常用到,希望大家都能掌握。

原文地址:https://www.cnblogs.com/dingjin/p/8446213.html

时间: 2024-10-10 08:22:02

转多线程设计模式 - Future模式之JAVA原生实现的相关文章

多线程设计模式 - Future模式之JAVA实现

在之前一篇博客中介绍了Future设计模式的设计思想以及具体实现,今天我们来讲一下使用JDK原生的包如何实现. JDK内置的Future主要使用到了Callable接口和FutureTask类. Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务.Callable接口的定义如下: public interface Callable<V> { /** * Computes a result, or throws an

多线程设计模式 - Future模式

Future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用.这类似我们日常生活中的在线购物流程,带在购物网看着一件商品时可以提交表单,当订单完成后就可以在家里等待商品送货上门.或者说更形象的是我们发送Ajax请求的时候,页面是异步的进行后台处理,用户无需等待请求的结果,可以继续浏览或操作其他内容. 如上图所示,客户端调用购物请求,服务端程序不等数据处理完成便立即返回客户端一个伪造的数据,(相当于订单,而不是真实的商品)这时候由服务端自己偷偷摸摸的发送了一个other call(

利用多线程实现Future模式

一.Futrue模式 客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据(相当于商品订单,不是商品本身),用户也无需等待,先去执行其他的若干操作后,再去调用服务器已经完成组装的真实数据. 该模型充分利用了等待的时间片段.简单来说就是,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果是再取真实的结果. 在多线程中经常举的一个例子就是:网络图片的下载,刚开始是通过模糊的图片来代替最后的图片,等下载图片的

多线程设计模式——Read-Write Lock模式和Future模式分析

目录 多线程程序评价标准 任何模式都有一个相同的"中心思想" Read-Write Lock 模式 RW-Lock模式特点 冲突总结 手搓RW Lock模式代码 类图 Data类 P.S. Before/After模式 ReadWriteLock类 正确运行结果 适用场合 "逻辑锁"vs"物理锁" 性能对比 "中心思想"分析 Future 模式 Future模式特点 手搓Future模式代码 类图 Main类 Host类 Fu

Java Future模式实现

Java Future模式简介 Future模式是Java多线程常用的模式,而且JDK也内置对Future模式的支持,比如在java.util.concurrent包下的FutureTask类.其核心思想在于:发出请求后,可以立即返回对象,但是这个对象实际上是个假对象,并不可立即使用,但是我们可以在干点别的事情后,就可以使用这个假对象获取结果了.这是为什么呢?因为在返回假对象的时候,偷偷的开启了一个线程去请求真正的结果数据.那么下面,我们来模拟实现下Future模式. 代码实现与分析 主流程是:

23种设计模式介绍以及在Java中的实现

原创不易,转载请注明出处:http://anxpp.com/,谢谢!     文章比较长,读者可以通过顶端的目录选择要了解的模式,然后通过文章右边的按钮快速返回顶部重新选择一个新的模式浏览 博主精心准备了大量的示例代码.文章尽量提供与编程相关的例子,而不是像多数其他介绍的文章一样,提供一些感觉挺滑稽的例子(那样的例子可能看完觉得写得很好,然而还是不会用...). 本文耗费了作者大量时间,还请亲们给个赞O(∩_∩)O~ 也可以通过CTRL+F并输入要了解的模式并跳到对应位置. 文章中的示例源码在g

多线程设计模式总结(一)

并发程序的编程与设计是一个难点,也是程序员必须掌握的一个点.工作之后写的第一个软件里面也有并发编程,当时在设计并发这块感觉好复杂,最后的实现感觉也有点乱. 当时就想好好学习一下并发编程的设计,但是一直没有时间.今年看了两本并发编程相关的书,<多线程设计模式>和<Java并发编程与实战>.本想着和设计模式一样,多线程设计模式也能提供很多模式可供套用,但是实际情况并不是如此,多线程设计模式讲的东西多为基础,并且内容也已经有点过时了,市面上<多线程设计模式>这本书也已经很难买

同步调用,异步回调和 Future 模式

目标 通过与方法的同步调用,异步回调比较,理解 Future 模式 三者的不同 让我们先来明确一下同步与异步的不同.我们这里所说的同步和异步,仅局限在方法的同步调用和异步回调中.即,同步指的是调用一个方法,调用方要等待该方法所执行的任务完全执行完毕,然后控制权回到调用方:异步指的是调用一个方法,调用方不等该方法执行的任务完毕就返回,当任务执行完毕时会自动执行调用方传入的一块代码. 同步调用 void runTask { doTask1() doTask2() } 同步调用,执行完 doTask1

Java多线程编程中Future模式的详解&lt;转&gt;

Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Future模式,关于其他多线程设计模式的地址如下:关于其他多线程设计模式的地址如下:关于Master-Worker模式的详解: Java多线程编程中Master-Worker模式的详解关于Guarded Suspeionsion模式的详解: Java多线程编程中Guarded Suspeionsion模式