submit方法:

public abstract class AbstractExecutorService implements ExecutorService {

    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();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
} 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;
} public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
//....
}
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
   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 class FutureTask<V> implements RunnableFuture<V> {

    private final java.util.concurrent.FutureTask.Sync sync;

    public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new java.util.concurrent.FutureTask.Sync(callable);
} public FutureTask(Runnable runnable, V result) {
sync = new java.util.concurrent.FutureTask.Sync(Executors.callable(runnable, result));
}
//....
}

submit返回的最终是FutureTask对象

execute方法:

public interface Executor {

    void execute(Runnable command);
}

具体的实现在ThreadPoolExecutor类中

    public void execute(Runnable command) {
if (command == null)
throw new NullPointerException(); int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}

submit内部调用execute

submit有返回值

submit方便exception处理

submit的demo:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<String>> resultList = new ArrayList<Future<String>>(); // 创建10个任务并执行
for (int i = 0; i < 10; i++) {
// 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
Future<String> future = executorService.submit(new TaskWithResult(i));
// 将任务执行结果存储到List中
resultList.add(future);
}
executorService.shutdown(); // 遍历任务的结果
for (Future<String> fs : resultList) {
try {
System.out.println(fs.get()); // 打印各个线程(任务)执行的结果
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
executorService.shutdownNow();
e.printStackTrace();
return;
}
}
}
}
class TaskWithResult implements Callable<String> {
private int id; public TaskWithResult(int id) {
this.id = id;
} /**
* 任务的具体过程,一旦任务传给ExecutorService的submit方法,则该方法自动在一个线程上执行。
*
* @return
* @throws Exception
*/
public String call() throws Exception {
System.out.println("call()方法被自动调用,干活!!! " + Thread.currentThread().getName());
if (new Random().nextBoolean())
throw new TaskException("Meet error in task." + Thread.currentThread().getName());
// 一个模拟耗时的操作
for (int i =9; i > 0; i--)
;
return "call()方法被自动调用,任务的结果是:" + id + " " + Thread.currentThread().getName();
}
} class TaskException extends Exception {
public TaskException(String message) {
super(message);
}
}
call()方法被自动调用,干活!!!             pool-1-thread-5
call()方法被自动调用,干活!!! pool-1-thread-1
call()方法被自动调用,干活!!! pool-1-thread-2
call()方法被自动调用,干活!!! pool-1-thread-4
call()方法被自动调用,干活!!! pool-1-thread-6
call()方法被自动调用,干活!!! pool-1-thread-6
call()方法被自动调用,干活!!! pool-1-thread-4
call()方法被自动调用,干活!!! pool-1-thread-2
call()方法被自动调用,干活!!! pool-1-thread-3
call()方法被自动调用,干活!!! pool-1-thread-7
call()方法被自动调用,任务的结果是:0 pool-1-thread-1
call()方法被自动调用,任务的结果是:1 pool-1-thread-2
java.util.concurrent.ExecutionException: com.company.TaskException: Meet error in task.pool-1-thread-3
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.company.Main.main(Main.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: com.company.TaskException: Meet error in task.pool-1-thread-3
at com.company.TaskWithResult.call(Main.java:56)
at com.company.TaskWithResult.call(Main.java:40)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

Runnable和Callable的区别是,
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

http://blog.csdn.net/yuzhiboyi/article/details/7775266

http://blog.csdn.net/zhangzhaokun/article/details/6615454

http://blog.csdn.net/xtwolf008/article/details/7713580

Java 线程池submit和execute的更多相关文章

  1. 血的教训--如何正确使用线程池submit和execute方法

    血的教训之背景:使用线程池对存量数据进行迁移,但是总有一批数据迁移失败,无异常日志打印 凶案起因 ​ 听说parallelStream并行流是个好东西,由于日常开发stream串行流的场景比较多,这次 ...

  2. Java线程池ThreadPoolExecuter:execute()原理

    一.线程池执行任务的流程 如果线程池工作线程数<corePoolSize,创建新线程执行task,并不断轮训t等待队列处理task. 如果线程池工作线程数>=corePoolSize并且等 ...

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

    在上一篇<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法.这篇文章是接着上一篇文章 ...

  4. Java线程池使用和分析(二) - execute()原理

    相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的 ...

  5. Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  6. 【Java线程池快速学习教程】

    1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变 ...

  7. Java线程池学习

    Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...

  8. java线程池的使用与详解

    java线程池的使用与详解 [转载]本文转载自两篇博文:  1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html   ...

  9. java线程池分析和应用

    比较 在前面的一些文章里,我们已经讨论了手工创建和管理线程.在实际应用中我们有的时候也会经常听到线程池这个概念.在这里,我们可以先针对手工创建管理线程和通过线程池来管理做一个比较.通常,我们如果手工创 ...

随机推荐

  1. Java Filter过滤xss注入非法参数的方法

    http://blog.csdn.NET/feng_an_qi/article/details/45666813 Java Filter过滤xss注入非法参数的方法 web.xml: <filt ...

  2. 剖析Docker文件系统:Aufs与Devicemapper

    http://www.infoq.com/cn/articles/analysis-of-docker-file-system-aufs-and-devicemapper Docker镜像 典型的Li ...

  3. 并发编程&数据库 - 考核题

    第八章主要内容 第八章:线程.进程.队列.IO多路模型 操作系统工作原理介绍.线程.进程演化史.特点.区别.互斥锁.信号.事件.join.GIL.进程间通信.管道.队列. 生产者消息者模型.异步模型. ...

  4. SVN部署

    1.安装SVN yum install subversion –y 2.配置SVN 建立SVN版本库数据存储目录(svndata)及用户.密码权限目录(svnpasswd) mkdir -p /app ...

  5. 【python】常用函数

    使用list生成dict(可指定单条长度和数据类型,splen为4即为list中每4行组成dict中一条) def list2dict(srclist,splen,datatype):# dataty ...

  6. python脚本前两行

    1. 第一行指定解释器路径 推荐写法: #!/usr/bin/env python 详细说明: #!/usr/bin/python是告诉操作系统执行这个脚本的时候,调用/usr/bin下的python ...

  7. Python面向对象高级

    一  反射 反射也可以说是python的自省机制 反射就是通过字符串的形式,导入模块,然后以字符串的形式去查找指定函数并执行.利用字符串的形式去模块(对象)中操作(查找/获取/添加/删除)属性,是一种 ...

  8. oracle建表设置主键自增

    首先创建一张表 create table member( memberId number primary key, memberMail )not null, memberName ) not nul ...

  9. ALV tree DUMP 问题处理-20180328

    Category ABAP Programming Error Runtime Errors MESSAGE_TYPE_X ABAP Program SAPLOLEA Application Comp ...

  10. C语言字符串/数组去重

    输入: hello 输出: helo 第一种实现: 不新开数组, 也就是原地去重. #include <stdio.h> #include <string.h> void re ...