代码示例:

public class ThreadPool_Test {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool = Executors.newCachedThreadPool();
pool.execute(new MyRunner()); Future<String> future = pool.submit(new MyCaller());
String ret = future.get();
System.out.println(ret);
}
} class MyCaller implements Callable<String> { @Override
public String call() throws Exception {
System.out.println("calling");
return "return_from_call";
} } class MyRunner implements Runnable {
@Override
public void run() {
System.out.println("running");
} }

execute 方法执行 runnable 任务,submit 方法执行 callable 任务,callable 任务有返回值,而 runnable 任务是 void 的,无返回值。

// void java.util.concurrent.ThreadPoolExecutor
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}

对于 Runnable,task 是 MyRunner,对于 Callable,task 是 FutureTask。

submit 方法的调用栈:

创建 FutureTask 对象,把 Callable 对象包裹起来,在 run 方法中调用 Callable 对象的方法,并设置返回值。

// java.util.concurrent.FutureTask.FutureTask
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
} public void run() {
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 {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}

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

  1. 详解线程池execute和submit用法

    在使用线程池时,我们都知道线程池有两种提交任务的方式,那么他们有什么区别呢? 1.execute提交的是Runnable类型的任务,而submit提交的是Callable或者Runnable类型的任务 ...

  2. 线程池提交任务的两种方式:execute与submit的区别

    Java中的线程池在进行任务提交时,有两种方式:execute和submit方法. 一.execute和submit的区别 execute只能提交Runnable类型的任务,无返回值.submit既可 ...

  3. execute和submit的区别与联系

    execute和submit都属于线程池的方法,execute只能提交Runnable类型的任务,而submit既能提交Runnable类型任务也能提交Callable类型任务. execute会直接 ...

  4. JAVA线程池shutdown和shutdownNow的区别

    一.区别介绍 shutDown()  当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态.此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionExcept ...

  5. ThreadPoolExecutor中execute和submit的区别

    1:入参不同 excute() 传入的是 Runable, submit 传入的是 Callable 或 Runable 1):execute 方法源码 public void execute(Run ...

  6. ScheduledThreadPoolExecutor线程池scheduleAtFixedRate和scheduleWithFixedDelay的区别

    ScheduledFuture<?> result = executor.scheduleAtFixedRate(task,2, 5, TimeUnit.SECONDS); 在延迟2秒之后 ...

  7. Java 并发编程——Executor框架和线程池原理

    Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...

  8. Java提高班(二)深入理解线程池ThreadPool

    本文你将获得以下信息: 线程池源码解读 线程池执行流程分析 带返回值的线程池实现 延迟线程池实现 为了方便读者理解,本文会由浅入深,先从线程池的使用开始再延伸到源码解读和源码分析等高级内容,读者可根据 ...

  9. 线程池-Executors

    合理使用线程池能够带来三个好处 减少创建和销毁线程上所花的时间以及系统资源的开销 提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行 提高线程的客观理性.线程是稀缺资源,如果无限制的创 ...

随机推荐

  1. JMeter 生成精度度为分钟的时间戳文件名

    import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import java.text.Simple ...

  2. python-ConfigParser模块【读写配置文件】

    对python 读写配置文件的具体方案的介绍 1,函数介绍 import configParser 如果Configparser无效将导入的configParser 的C小写 1.1.读取配置文件 - ...

  3. P3853 [TJOI2007]路标设置

    传送门 思路: 类似于数列分段的二分查找答案.设目前的 mid 是一个最小的“空旷指数”,那么在 sum 数组(路标数组)里每两个相邻间的路标距离一定要小于等于目前的 mid , 如果大于,那就必须使 ...

  4. System.arraycopy和arrays.copyOf

    public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length); 这 ...

  5. arcgis 属性表字段值计算

    1 如果你用VBSCRIPT的代码,那就在对应的选择项目处选择下,如果是PYTHON代码,就在另外一点点一下.如果弄混了,显然代码会报错. 2 VBSCRIPT里面的函数非常少,但是你可以去利用这些函 ...

  6. 学习笔记28—Python 不同数据类型取值方法

    1.array数据类型 1)-------> y[i,] 或者 y[i] 2.遍历目录下所有文件夹: def eachFile(filepath):     pathDir =  os.list ...

  7. QSplitter实现滑动窗口和悬浮按钮

    1         QSplitter实现滑动窗口和悬浮按钮 软件应用中需要设计右侧滑动窗口,通过一个按钮来实现窗口的隐藏和显示,应用场景比如显示主界面的详细信息. (1)   在qt design中 ...

  8. 关于Java实现的进制转化(位运算)

    一.需求: 最近在做文件传输的东西,文件传输当然是传输很重要,包括编码格式以及进制的统一. 简略的说一下这次做的东西:首先文件是按照块来发送的,一块一块大的发,但是,发送的过程是这样的: 先发送头部, ...

  9. mt19937 -- 高质量随机数

    优点:产生速度快, 周期大 用法: #include<bits/stdc++.h> using namespace std; int main() { mt19937 mt_rand(ti ...

  10. traceback模块——获取详细的异常信息

    try: 1/0 except Exception,e: print e 输出结果是integer division or modulo by zero,只知道是报了这个错,但是却不知道在哪个文件哪个 ...