13.ThreadPoolExecutor线程池之submit方法

更新时间:2023-07-22 21:32:03 阅读: 评论:0

13.ThreadPoolExecutor线程池之submit⽅法
jdk1.7.0_79
  在上⼀篇中提到了线程池ThreadPoolExecutor的原理以及它的execute⽅法。本⽂解析ThreadPoolExecutor#submit。
own  对于⼀个任务的执⾏有时我们不需要它返回结果,但是有我们需要它的返回执⾏结果。对于线程来讲,如果不需要它返回结果则实现Runnable,⽽如果需要执⾏结果的话则可以实现Callable。在线程池同样execute提供⼀个不需要返回结果的任务执⾏,⽽对于需要结果返回的则可调⽤其submit⽅法。
  回顾ThreadPoolExecutor的继承关系。
  在Executor接⼝中只定义了execute⽅法,⽽submit⽅法则是在ExecutorService接⼝中定义的。
//ExecutorService
public interface ExecutorService extends Executor {
  ...
  <T> Future<T> submit(Callable<T> task);
  <T> Future<T> submit(Runnable task, T result);
  <T> Future<T> submit(Runnable task);
  ...
}
  ⽽在其⼦类AbstractExecutorService实现了submit⽅法。
//AbstractExecutorService
考研考试时间
public abstract class AbstractExecutorService implements ExecutorService {
  ...
  public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
cha  }
  public <T> Future<T> submit(Runnable task, T result) {
    if (task == null) throw new NullPointerException();
三年级英语上册教学计划    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
  }
  public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerExeption();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
  }
  ...
}
  在AbstractExecutorService实现的submit⽅法实际上是⼀个模板⽅法,定义了submit⽅法的算法⾻架,其execute交给了⼦类。(可以看到在很多源码中,模板⽅法模式被⼤量运⽤,有关模板⽅法模式可参考)
  尽管submit⽅法能提供线程执⾏的返回值,但只有实现了Callable才会有返回值,⽽实现Runnable的线程则是没有返回值的,也就是说在上⾯的3个⽅法中,submit(Callable<T> task)能获取到它的返回值,submit(Runnable task, T result)能通过传⼊的载体result间接获得线程的返回值或者准确来说交给线程处理⼀下,⽽最后⼀个⽅法submit(Runnable task)则是没有返回值的,就算获取它的返回值也是null。
  下⾯给出3个例⼦,来感受下submit⽅法。
  submit(Callable<T> task)
package com.threadpoolexecutor;
import urrent.*;
/**
* ThreadPoolExecutor#sumit(Callable<T> task)
* Created by yulinfeng on 6/17/17.
*/
public class Sumit1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<String> callable = new Callable<String>() {
public String call() throws Exception {
System.out.println("This is ThreadPoolExetor#submit(Callable<T> task) method.");
return "result";
}
};
ExecutorService executor = wSingleThreadExecutor();
Future<String> future = executor.submit(callable);
System.out.());
}
}
  submit(Runnable task, T result)
package com.threadpoolexecutor;
lloyds tsb
import urrent.ExecutionException;
import urrent.ExecutorService;
import urrent.Executors;
import urrent.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 = wSingleThreadExecutor();
Data data = new Data();
Future<Data> future = executor.submit(new Task(data), data);
System.out.().getName());
}
}
class Data {
String name;
public String getName() {
return name;
}
public void tName(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.tName("kevin");
}
}java软件培训
  submit(Runnable task)
少儿口语package com.threadpoolexecutor;
import urrent.ExecutionException;
import urrent.ExecutorService;
import urrent.Executors;
import urrent.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 = wSingleThreadExecutor();
Future future = executor.submit(runnable);
System.out.());
}
}
美好的回忆英文  通过上⾯的实例可以看到在调⽤submit(Runnable runnable)的时候是不需要其定义类型的,也就是说虽然在ExecutorService中对其定义的是泛型⽅法,⽽在AbstractExecutorService中则不是泛型⽅法,因为它没有返回值。(有关Object、T、?这三者的区别,可参考)。
spoiler  从上⾯的源码可以看到,这三者⽅法⼏乎是⼀样的,关键就在于:
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
  它是如何将⼀个任务作为参数传递给了newTaskFor,然后调⽤execute⽅法,最后进⽽返回ftask的呢?高级翻译张璐
//AbstractExecutorService#newTaskFor
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
  return new FutureTask<T>(callable);
}
  protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
  return new FutureTask<T>(runnable, value);
}
  看来是返回了⼀个FutureTask实例,FutureTask实现了Future和Runnable接⼝。Future接⼝是Java线程Future模式的实现,可⽤⽤来异步计算,实现Runnable接⼝表⽰可以作为⼀个线程执⾏。Future
Task实现了这两个接⼝意味着它代表异步计算的结果,同时可以作为⼀个线程交给Executor来执⾏。有关FutureTask放到下章来单独解析。所以本⽂对于线程池ThreadPoolExecutor线程池的submit⽅法解析并不完整,必须得了解Java线程的Future模式——。

本文发布于:2023-07-22 21:32:03,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/185602.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线程   结果   返回值   需要   返回   实现   模式   个例
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图