线程池-任务提交

任务提交有两种方式:

  • submit 提交Runable任务
  • execute 提交Callable任务
submit 提交Runable
  • 方式1 future返回null
    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }
  • 方式2 future返回指定结果
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }
  • 方式3 future返回Callable的结果T
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

跟入newTaskFor代码,再看 FutureTask的构造可知,以上三种方式都是将提交的任务转换为一个callable对象,包装到FutureTask实例中进行处理,感兴趣的runnable的返回结果处理是这样的:

    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }
    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

callable 在创建RunnableAdapter

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

RunnableAdapter 里能看到call的执行逻辑,执行完run,返回result;

    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;
        }
    }
execute 提交Callable任务

当Callable对象构造完毕后,放入RunnableFuture实例中;FutureTask本身是Runnable接口,作为Executor接口中声明的execute方法的参数进行处理,必定会调用其run方法,看其实现:

  • FutureTask#run()
    简化以下其run方法的代码,可以看出会执行callable#call方法,并保存结果。
    public void run() {
            Callable<V> c = callable;
            result = c.call();
            set(result);
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。