首页 > 编程语言 >JAVA线程池 submit方法返回值

JAVA线程池 submit方法返回值

时间:2023-01-15 15:47:30浏览次数:61  
标签:task JAVA submit callable private 线程 result FutureTask public

JAVA线程池 submit方法返回值

AbstractExecutorService

 public abstract class AbstractExecutorService implements ExecutorService {
 
     // RunnableFuture 是用于获取执行结果的,我们常用它的子类 FutureTask
     // 下面两个 newTaskFor 方法用于将我们的任务包装成 FutureTask 提交到线程池中执行
     protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
         return new FutureTask<T>(runnable, value);
     }
 
     protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
         return new FutureTask<T>(callable);
     }
 
     // 提交任务
     public Future<?> submit(Runnable task) {
         if (task == null) throw new NullPointerException();
         // 1. 将任务包装成 FutureTask
         RunnableFuture<Void> ftask = newTaskFor(task, null);
         // 2. 交给执行器执行,execute 方法由具体的子类来实现
         // 前面也说了,FutureTask 间接实现了Runnable 接口。
         execute(ftask);
         return ftask;
     }
 
     public <T> Future<T> submit(Runnable task, T result) {
         if (task == null) throw new NullPointerException();
         // 1. 将任务包装成 FutureTask
         RunnableFuture<T> ftask = newTaskFor(task, result);
         // 2. 交给执行器执行
         execute(ftask);
         return ftask;
     }
 
     public <T> Future<T> submit(Callable<T> task) {
         if (task == null) throw new NullPointerException();
         // 1. 将任务包装成 FutureTask
         RunnableFuture<T> ftask = newTaskFor(task);
         // 2. 交给执行器执行
         execute(ftask);
         return ftask;
     }
 }

RunnableFuture

public interface RunnableFuture<V> extends Runnable, Future<V> {
    /**
     * Sets this Future to the result of its computation
     * unless it has been cancelled.
     */
    void run();
}

FutureTask

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; //任务正常完成,结果被set 
     private static final int EXCEPTIONAL = 3; //任务抛出异常 
     private static final int CANCELLED = 4; //任务已被取消 
     private static final int INTERRUPTING = 5; //线程中断状态被设置ture,但线程未响应中断 
     private static final int INTERRUPTED = 6; //线程已被中断 
 
     //将要执行的任务 
     private Callable<V> callable; //用于get()返回的结果,也可能是用于get()方法抛出的异常 
     private Object outcome; // non-volatile, protected by state reads/writes //执行callable的线程,调用FutureTask.run()方法通过CAS设置 
     private volatile Thread runner; //栈结构的等待队列,该节点是栈中的最顶层节点。 
     private volatile WaitNode waiters; 
 
     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
    }
    
    protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }
    
    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

    /**
     * @throws CancellationException {@inheritDoc}
     */
    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);
    }
    
    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);
    }
    
    public void run() {
         //保证callable任务只被运行一次
         if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread()))
             return;
         try {
             Callable < V > c = callable;
             if (c != null && state == NEW) {
                 V result;
                 boolean ran;
                 try { 
                     //执行任务,上面的例子我们可以看出,call()里面可能是一个耗时的操作,不过这里是同步的
                     result = c.call();
                     //上面的call()是同步的,只有上面的result有了结果才会继续执行
                     ran = true;
                 } catch (Throwable ex) {
                     result = null;
                     ran = false;
                     setException(ex);
                 }
                 if (ran)
                     //执行完了,设置result
                     set(result);
             }
         }
         finally {
             runner = null;
             int s = state;
             //判断该任务是否正在响应中断,如果中断没有完成,则等待中断操作完成
             if (s >= INTERRUPTING)
                 handlePossibleCancellationInterrupt(s);
         }
    }
    ....
}

Excutor内部方法

    public static <T> Callable<T> callable(Runnable task, T result) {
        if (task == null)
            throw new NullPointerException();
        return new RunnableAdapter<T>(task, result);
    }

Excutor内部类RunnableAdapter

    static final class RunnableAdapter<T> implements Callable<T> {
        final Runnable task;
        final T result;
        RunnableAdapter(Runnable task, T result) {
            this.task = task;
            this.result = result;
        }
        public T call() {
            task.run();
            return result;
        }
    }

为什么AbstractExecutorService中submit方法内部使用的是excute,但是却有返回值

传入的任务如果是实现Runnable接口的,会通过RunnableAdapter方式转换成Callable

最终执行的是FutureTask中的run方法,结果赋值给Object outcome,通过get获取,返回outcome.

参考:

并发编程(十二)—— Java 线程池 实现原理与源码深度解析 之 submit 方法 (二)

标签:task,JAVA,submit,callable,private,线程,result,FutureTask,public
From: https://www.cnblogs.com/hongdada/p/17053595.html

相关文章

  • 12.(结构型模式)java设计模式之享元模式
    一、什么是享元模式Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意。享元模式是对象的结构......
  • 第一个 Java 程序
    本节我们将以 Windows 操作系统为例,编写并执行第一个 J**a 程序。在这之前,请确保你的操作系统上已经安装了JDK1.编译程序大家可能有个疑问,为什么需要编译程序呢?计......
  • Java入门关于JDK
    Java入门JDKJDK:JavaDevelopmentKitJDK是JavaDevelopmentKit的缩写,是Java的开发工具包。JDK:JavaDevelopmentToolKit(Java开发工具包)。JDK是整个JAVA的核心,包......
  • Error:java: Compilation failed: internal java compiler error 解决办法
    编译时提示错误 Error:java:Compilationfailed:internaljavacompilererror 1、查看项目的jdk(Ctrl+Alt+shift+S)File->ProjectStructure->ProjectSettings->......
  • 一步一步实现若依框架--2.3防止重复提交(后台) repeat_submit
    原理:常见的场景端页面多次点击提交按钮,通常见到的是前端通过点击一次后使按钮disable进行处理,后端同样也需要进行限制。若依使用了注解+拦截器的方式,这里其实也可以用......
  • JAVASE基础强化Day2
    总结:数据类型:基本数据类型,引用数据类型八大基本数据类型:Byte:字节类型:1个字节,8个bit,在内存中开辟8个bit的空间每个bit就是二进制的 Short:2个字节,8*2=16个bit,在内存中......
  • 哪种编程语言更适合编写Selenium Web驱动程序脚本,Python还是Java?
    在本文中,我们将学习哪种编程语言更适合编写SeleniumWeb驱动程序脚本,Python或Java。从选项池中选择理想的编程语言可能很困难。Python,Java和Selenium都有自己的一套功能。越......
  • Javascript脚本运算符执行顺序对照表
    Javascript脚本运算符执行顺序对照表:在线查看Javascript脚本运算符执行优先级别 ​​窍门:Ctrl+F快速查找​​Javascript脚本运算符优先级,是描述在计算机计算表达式时执行......
  • Javascript事件与功能说明大全
    Javascript事件与功能说明大全 ​​窍门:Ctrl+F快速查找​​总结了Javascript常用的各种事件,包括鼠标事件、加载事件、滚动事件、表单事件、编辑事件、数据绑定事件等下表......
  • java多线程编程技术 +代码实例
    1.      java和他的API都可以使用并发。可以指定程序包含不同的执行线程,每个线程都具有自己的方法调用堆栈和程序计数器,使得线程在与其他线程并发地执行能够共享程序......