0

0

ThreadPoolExecutor线程池之submit方法

巴扎黑

巴扎黑

发布时间:2017-06-26 11:33:07

|

2209人浏览过

|

来源于php中文网

原创

jdk1.7.0_79 

  在上一篇《ThreadPoolExecutor线程池原理及其execute方法》中提到了线程池ThreadPoolExecutor的原理以及它的execute方法。本文解析ThreadPoolExecutor#submit。

  对于一个任务的执行有时我们不需要它返回结果,但是有我们需要它的返回执行结果。对于线程来讲,如果不需要它返回结果则实现Runnable,而如果需要执行结果的话则可以实现Callable。在线程池同样execute提供一个不需要返回结果的任务执行,而对于需要结果返回的则可调用其submit方法。

  回顾ThreadPoolExecutor的继承关系。

  

  在Executor接口中只定义了execute方法,而submit方法则是在ExecutorService接口中定义的。

  

//ExecutorServicepublic interface ExecutorService extends Executor {
  ...
   Future submit(Callable task);
   Future submit(Runnable task, T result);
   Future submit(Runnable task);
  ...
}

  而在其子类AbstractExecutorService实现了submit方法。

//AbstractExecutorServicepublic abstract class AbstractExecutorService implements ExecutorService {
  ...
  public  Future submit(Callable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
  }
  public  Future submit(Runnable task, T result) {
    if (task == null) throw new NullPointerException();
    RunnableFuture ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
  }
  public Future submit(Runnable task) {
    if (task == null) throw new NullPointerExeption();
    RunnableFuture ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask; 
  }
  ...
}

  在AbstractExecutorService实现的submit方法实际上是一个模板方法,定义了submit方法的算法骨架,其execute交给了子类。(可以看到在很多源码中,模板方法模式被大量运用,有关模板方法模式可参考《模板方法模式》)

  尽管submit方法能提供线程执行的返回值,但只有实现了Callable才会有返回值,而实现Runnable的线程则是没有返回值的,也就是说在上面的3个方法中,submit(Callable task)能获取到它的返回值,submit(Runnable task, T result)能通过传入的载体result间接获得线程的返回值或者准确来说交给线程处理一下,而最后一个方法submit(Runnable task)则是没有返回值的,就算获取它的返回值也是null。

神笔马良
神笔马良

神笔马良 - AI让剧本一键成片。

下载

  下面给出3个例子,来感受下submit方法。

  submit(Callable task)

package com.threadpoolexecutor;import java.util.concurrent.*;/**
 * ThreadPoolExecutor#sumit(Callable task)
 * Created by yulinfeng on 6/17/17. */public class Sumit1 {public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable callable = new Callable() {public String call() throws Exception {
                System.out.println("This is ThreadPoolExetor#submit(Callable task) method.");return "result";
            }
        };

        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future future = executor.submit(callable);
        System.out.println(future.get());
    }
}

  submit(Runnable task, T result)

package com.threadpoolexecutor;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;/**
 * ThreadPoolExecutor#submit(Runnable task, T result)
 * Created by yulinfeng on 6/17/17. */public class Submit2 {public static void main(String[] args) throws ExecutionException, InterruptedException {

        ExecutorService executor = Executors.newSingleThreadExecutor();
        Data data = new Data();
        Future future = executor.submit(new Task(data), data);
        System.out.println(future.get().getName());
    }
}class Data {
    String name;public String getName() {return name;
    }public void setName(String name) {this.name = name;
    }
}class Task implements Runnable {
    Data data;public Task(Data data) {this.data = data;
    }public void run() {
        System.out.println("This is ThreadPoolExetor#submit(Runnable task, T result) method.");
        data.setName("kevin");
    }
}

  submit(Runnable task)

package com.threadpoolexecutor;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;/**
 * ThreadPoolExecutor#sumit(Runnable runnables)
 * Created by yulinfeng on 6/17/17. */public class Submit {public static void main(String[] args) throws ExecutionException, InterruptedException {
        Runnable runnable = new Runnable() {public void run() {
                System.out.println("This is ThreadPoolExetor#submit(Runnable runnable) method.");
            }
        };

        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future future = executor.submit(runnable);
        System.out.println(future.get());
    }
}

  通过上面的实例可以看到在调用submit(Runnable runnable)的时候是不需要其定义类型的,也就是说虽然在ExecutorService中对其定义的是泛型方法,而在AbstractExecutorService中则不是泛型方法,因为它没有返回值。(有关Object、T、?这三者的区别,可参考《Java中的Object、T(泛型)、?区别》)。

  从上面的源码可以看到,这三者方法几乎是一样的,关键就在于:

RunnableFuture ftask = newTaskFor(task);
execute(ftask);

  它是如何将一个任务作为参数传递给了newTaskFor,然后调用execute方法,最后进而返回ftask的呢?

//AbstractExecutorService#newTaskForprotected  RunnableFuture newTaskFor(Callable callable) {
  return new FutureTask(callable);
}
  protected  RunnableFuture newTaskFor(Runnable runnable, T value) {
  return new FutureTask(runnable, value);
}

  看来是返回了一个FutureTask实例,FutureTask实现了Future和Runnable接口。Future接口是Java线程Future模式的实现,可用用来异步计算,实现Runnable接口表示可以作为一个线程执行。FutureTask实现了这两个接口意味着它代表异步计算的结果,同时可以作为一个线程交给Executor来执行。有关FutureTask放到下章来单独解析。所以本文对于线程池ThreadPoolExecutor线程池的submit方法解析并不完整,必须得了解Java线程的Future模式——《14.Java中的Future模式》。

相关专题

更多
c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

79

2026.01.09

c++框架学习教程汇总
c++框架学习教程汇总

本专题整合了c++框架学习教程汇总,阅读专题下面的文章了解更多详细内容。

46

2026.01.09

学python好用的网站推荐
学python好用的网站推荐

本专题整合了python学习教程汇总,阅读专题下面的文章了解更多详细内容。

121

2026.01.09

学python网站汇总
学python网站汇总

本专题整合了学python网站汇总,阅读专题下面的文章了解更多详细内容。

12

2026.01.09

python学习网站
python学习网站

本专题整合了python学习相关推荐汇总,阅读专题下面的文章了解更多详细内容。

15

2026.01.09

俄罗斯手机浏览器地址汇总
俄罗斯手机浏览器地址汇总

汇总俄罗斯Yandex手机浏览器官方网址入口,涵盖国际版与俄语版,适配移动端访问,一键直达搜索、地图、新闻等核心服务。

71

2026.01.09

漫蛙稳定版地址大全
漫蛙稳定版地址大全

漫蛙稳定版地址大全汇总最新可用入口,包含漫蛙manwa漫画防走失官网链接,确保用户随时畅读海量正版漫画资源,建议收藏备用,避免因域名变动无法访问。

370

2026.01.09

php学习网站大全
php学习网站大全

精选多个优质PHP入门学习网站,涵盖教程、实战与文档,适合零基础到进阶开发者,助你高效掌握PHP编程。

45

2026.01.09

php网站搭建教程大全
php网站搭建教程大全

本合集专为零基础用户打造,涵盖PHP网站搭建全流程,从环境配置到实战开发,免费、易懂、系统化,助你快速入门建站!

12

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django DRF 源码解析
Django DRF 源码解析

共21课时 | 1.4万人学习

HTML常用元素与表单常用控件
HTML常用元素与表单常用控件

共12课时 | 2.2万人学习

CSS3 教程
CSS3 教程

共18课时 | 4.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号