FutureTask与Callable运用

  最近项目需要用到FutureTask异步获取执行结果,并与Callable结合起来运用。

  首先,看下FutureTask执行过程:FutureTask可用于异步获取执行结果或取消执行任务的场景。通过传入Runnable或Callable的任务给FutureTask,

直接调用其run方法或者放入线程池执行,然后通过FutureTask的get方法异步获取执行结果。

下面直接看代码。

Service.java   ---服务类

//1、new一个线程池,属于成员变量,在项目启动时就初始化
private static final ExecutorService exec =  Executors.newFixedThreadPool(100);
public FutureTask<List> getFutureTask() {
        //2、创建FutureTask任务对象,传参Callable
        FutureTask<List> ft = new FutureTask<List>(new Callable<List>() {
            //实现Callable的call()方法
            @Override
            public List call() throws Exception {
                //3、进行业务操作
                List re = "";
                //4、返回业务结果
                return re;
            }
        });
        //5、把FutureTask任务提交到线程池
        exec.submit(ft);
        //6、并返回FutureTask
        return ft;
    }

Action.java----业务类

//6、获取任务,传参objList(业务参数)
FutureTask<List> futureTask = taskService.getFutureTask();
//8、get()获取业务操作结果。
List taskList = futureTask.get(20, TimeUnit.SECONDS);

下面看源码实现

public class FutureTask<V> implements RunnableFuture<V>
    private volatile int state;
    private static final int NEW          = 0;
    private static final int COMPLETING   = 1;
    private static final int NORMAL       = 2;
    private static final int EXCEPTIONAL  = 3;
    private static final int CANCELLED    = 4;
    private static final int INTERRUPTING = 5;
    private static final int INTERRUPTED  = 6;

    private Callable<V> callable;
    private Object outcome; // non-volatile, protected by state reads/writes

     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
    }
    //。。。。。。省略
}

FutureTask类实现了RunnableFuture接口,同时RunnableFuture继承了Runnable接口和Future接口。

state修饰变量是volatie,对整个线程是可见的。

outcome ,属于non-valatie,是为了在读写时候做了自我保护

FutureTask提供了2个构造器:FutureTask(Callable<V> callable)和FutureTask(Runnable runnable, V result) 分别实现了Callable和Runnable方法。

调用这个两个构造器时,state状态为NEW

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;
}

FutureTask(Callable<V> callable)实现了Callable的call()方法,并返回V结果

public V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (unit == null)
            throw new NullPointerException();
        int s = state;
        if (s <= COMPLETING &&
            (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
            throw new TimeoutException();
        return report(s);
    }

    /**
     * Returns result or throws exception for completed task.
     *
     * @param s completed state value
     */
    @SuppressWarnings("unchecked")
    private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }
 protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }
futureTask.get(20, TimeUnit.SECONDS),通过get()方法获取结果,并设定阻塞时间
时间: 2024-08-07 04:22:13

FutureTask与Callable运用的相关文章

java多线程开发,Executors、FutureTask、Callable

java多线程如何应用呢,几乎学java的同学都知道Thread类和Runable接口.继承Thread类或者实现Runable接口,调用thread的start方法即可启动线程. 然后是线程池,就是启动一系列的线程,当需要启动某个线程时,从线程池中拿取一个线程. 最近使用到需要启动一个线程进行复杂运算并且得到其返回值. 就用到Callable. public interface Callable<V> { /** * Computes a result, or throws an excep

Java_并发线程_Futrue、FutureTask、Callable

1.Futrue public interface Future<V> //Future 表示异步计算的结果 ExecutorService threadPool = Executors.newSingleThreadExecutor(); Future<String> future = threadPool.submit(new Callable<String>() { public String call() throws Exception { Thread.sl

java多线程编程之Future/FutureTask和Callable

有这样一种场景,用多线程发送数据到某个服务器,需要知道各个线程是否都发送成功,等所有线程都发送完成才能继续下一轮计算和发送.如果用传统的多线程方式,就需要启动多个线程,然后在每个线程中分别发送数据,外部通过某种方式等待各个线程全部都发送完成,再进行后面的计算等流程.这种实现方式的代码会比较臃肿,在java中提供了一种Callable+Future的方法,可以将异步的多线程调用变为同步方式. Callable 在java的多线程编程中,有Thread和Runnable两种方式来新建线程,其中Run

Java 如何实现线程间通信?(notify、join、CountdownLatch、CyclicBarrier、FutureTask、Callable )

转自:https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247486499&idx=1&sn=d3f2d6959df7299bfbe2d663f6c4d353&chksm=ebd6330fdca1ba19316e89bedcaab01be8fdb81ba7ba3a9456c51fa28e80b2b1b33265d513ee&mpshare=1&scene=23&srcid=0113bUJHO

Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask

CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就是CyclicBarrier.CyclicBarrier从字面理解是指循环屏障,它可以协同多个线程,让多个线程在这个屏障前等待,直到所有线程都达到了这个屏障时,再一起继续执行后面的动作.看一下CyclicBarrier的使用实例: public static class CyclicBarrierThread extends Thread { private CyclicBarrier cb; private int sleep

Android进阶——多线程系列之Thread、Runnable、Callable、Future、FutureTask

多线程系列之Thread.Runnable.Callable.Future.FutureTask 前言 多线程一直是初学者最抵触的东西,如果你想进阶的话,那必须闯过这道难关,特别是多线程中Thread.Runnable.Callable.Future.FutureTask这几个类往往是初学者容易搞混的.这里先总结这几个类特点和区别,让大家带着模糊印象来学习这篇文章 Thread.Runnable.Callable:都是线程 Thread特点:提供了线程等待.线程睡眠.线程礼让等操作 Runnab

疯狂Java学习笔记(66)-----------Callable、Future和FutureTask

在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦. 而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果. 今天我们就来讨论一下Callable.Future和FutureTask三个类的使用方法.以下是本文的目录

Callable、FutureTask和Future详解带你理解java并发编程

一. Callable接口与Runnable接口区别 创建java线程,我们经常使用两种方式: 一是直接继承Thread 另一种是实现Runnable接口 但这两种方式有一个缺陷:在执行完任务之后无法直接获取执行结果. 1. 接口定义 1.1 Callable接口 public interface Callable<V> { V call() throws Exception; } 1.2 Runnable接口 public interface Runnable { public abstra

【转】Java线程系列:Callable和Future

一.前言 在研究JDK1.8的CompletableFuture时,顺道将Futrue一起扫了盲~这篇博文纯转载 二.正文 本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果.        Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值