`
san_yun
  • 浏览: 2652397 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

executor的execute和submit方法区别

 
阅读更多

executor经常会使用到,这里主要比较一下execute和submit方法的区别。

 

这个两个方法最主要的区别是如果runable中的方法抛出异常,execute会终止这个线程。而submit 不会。

 

这里分析一下原因。

 

测试代码:

ExecutorService es = Executors.newCachedThreadPool(namedThreadFactory);
		try {
			es.submit(new Runnable() {

				@Override
				public void run() {
					System.out.println("ok");
					throw new RuntimeException();
				}
			});
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		System.out.println("end");

 

其实两种方法提交给ThreadPoolExecutor执行的主要逻辑都是一致的,在ThreadPoolExecutor$Worker.run()中被执行,ThreadPoolExecutor$Worker是一个工作线程,每个Worker对象对应了一个线程, t会被调用start()。

    private Thread addThread(Runnable firstTask) {
        Worker w = new Worker(firstTask);
        Thread t = threadFactory.newThread(w);
        if (t != null) {
            w.thread = t;
            workers.add(w);
            int nt = ++poolSize;
            if (nt > largestPoolSize)
                largestPoolSize = nt;
        }
        return t;
    }

 

ThreadPoolExecutor$Worker.run():
	Runnable task = firstTask;
	firstTask = null;
	while (task != null || (task = getTask()) != null) {
	    runTask(task);
	    task = null;
	}

 注意如果没有没有任务,getTask会阻塞,然后都会执行runTask。 主要区别在于task对象的不同,sumit的task对象是FutureTask,而execute是一个普通的Runable。这里可以看到如果是Runable被执行调用run会抛出异常的,线程被中断。

runTask(Runnable task):
	boolean ran = false;
	beforeExecute(thread, task);
	try {
	    task.run();
	    ran = true;
	    afterExecute(task, null);
	    ++completedTasks;
	} catch (RuntimeException ex) {
	    if (!ran)
		afterExecute(task, ex);
	    throw ex;
	}

如果是FutureTask

void innerRun():
	try {
	    runner = Thread.currentThread();
	    if (getState() == RUNNING) 
		innerSet(callable.call());
	    else
		releaseShared(0); 
	} catch (Throwable ex) {
		innerSetException(ex);
	}

 

Thread [Action-thread-0] 	
	ThreadPoolExecutor$Worker.runTask(Runnable) line: 886	
	ThreadPoolExecutor$Worker.run() line: 908 [local variables unavailable]	
	Thread.run() line: 662	


Thread [Action-thread-0] 
	FutureTask$Sync.innerRun() line: 306 [local variables unavailable]	
	FutureTask<V>.run() line: 138 [local variables unavailable]	
	ThreadPoolExecutor$Worker.runTask(Runnable) line: 886	
	ThreadPoolExecutor$Worker.run() line: 908 [local variables unavailable]	
	Thread.run() line: 662	

 

 

分享到:
评论

相关推荐

    ExecutorService的execute和submit方法

    `ExecutorService`通过`execute()`和`submit()`这两个方法来提交任务进行执行。理解并熟练运用这两个方法对于优化并发性能至关重要。 `execute()`方法: `execute(Runnable command)`是`ExecutorService`最基础的...

    线程池的submit和execute的区别.md

    ### 线程池的submit和execute方法的区别详解 #### 一、引言 线程池作为Java并发编程中的一项关键技术,在实现高效并发任务管理方面发挥着重要作用。而在实际开发中,开发者经常会遇到两种用于向线程池提交任务的...

    Executor框架使用详解

    基于`Executor`,`ExecutorService`接口提供了更丰富的功能,如关闭线程池的`shutdown()`和`shutdownNow()`方法,以及管理和控制任务执行的方法,如`submit()`、`invokeAll()`和`invokeAny()`。`ExecutorService`...

    Executor,Executors,ExecutorService比较.docx

    `Executor`是Java线程池的顶级接口,它只有一个方法`execute(Runnable command)`,用于执行传入的任务。`Executor`并不直接创建线程,而是通过实现它的子接口或类来完成。通常,我们不会直接使用`Executor`,而是...

    线程池之Executor框架.docx

    - **任务执行**:核心接口`Executor`定义了任务的执行方法`execute()`,用于启动一个任务。`ExecutorService`接口继承自`Executor`,提供了更丰富的管理功能,如关闭线程池、管理线程等。`ThreadPoolExecutor`和`...

    并发编程之Executor线程池原理与源码解读.pdf

    线程池中重要的方法包括execute()、submit()、shutdown()、shutdownNow()、isTerminated()和isShutdown()等。execute()方法用于执行Runnable任务;submit()方法可以用来提交Callable或Runnable任务,并返回一个...

    java并发编程:Executor、Executors、ExecutorService.docx

    Java并发编程中的Executor、Executors和ExecutorService是Java并发编程框架的重要组成部分,它们为开发者提供了高效管理和控制线程执行的工具。以下是对这些概念的详细解释: 1. Executor: Executor是一个接口,它...

    Java多线程之Executor框架.docx

    Executor框架的核心接口是`Executor`,它只有一个方法`execute(Runnable command)`,用于执行给定的任务。`Executor`接口提供了任务执行的基本模型,但并未提供关闭或管理线程池的能力。 为了解决这个问题,`...

    简单谈谈ThreadPoolExecutor线程池之submit方法

    在 Executor 接口中,只定义了 execute 方法,而 submit 方法则是在 ExecutorService 接口中定义的。 ```java public interface ExecutorService extends Executor { ... &lt;T&gt; Future&lt;T&gt; submit(Callable&lt;T&gt; task)...

    掌握并发的钥匙:Java Executor框架深度解析

    - 使用`submit(Callable)`方法提交Callable任务并获取结果。 #### 代码示例:提交Runnable任务 ```java executor.execute(() -&gt; { System.out.println("Task running in thread: " + Thread.currentThread()....

    Java-Executor并发框架.docx

    真正实现线程池功能的是ExecutorService接口,它是Executor的子接口,提供了更多的管理和控制线程池的方法,如`shutdown()`和`submit()`等。 Executors类是一个工厂类,提供了一系列静态方法,用于创建不同类型的...

    2_ExecutorService源码阅读1

    execute() 方法用于执行给定的 Runnable 任务,它是提交任务的基础方法,submit() 实际上也是通过 execute() 来执行任务的。 总结来说,ExecutorService 是 Java 并发编程的重要组件,它提供了一套完善的机制来管理...

    Java中Future、FutureTask原理以及与线程池的搭配使用

    `Future`接口提供了对异步计算结果的访问和控制,而`FutureTask`是`Future`的一个具体实现,它还同时实现了`Runnable`接口,因此可以直接提交给`Executor`执行。 `Future`接口提供了以下方法: 1. `boolean cancel...

    几种方法编写线程代码

    Future&lt;Integer&gt; future = executor.submit(new Callable() { public Integer call() throws Exception { return calculateSomething(); } }); // 获取结果 Integer result = future.get(); ``` 5. Lambda表达式...

    21-多线程和线程同步1

    * ExecutorService 接口:提供了 execute() 方法、shutdown() 方法和 submit() 方法,用于执行 Runnable 任务和管理线程池。 * ThreadPoolExecutor 类:是一个线程池执行器,提供了一个固定大小的线程池。 Callable...

    Java线程创建的四种方式

    executor.execute(new Runnable() { public void run() { // 线程执行的任务 } }); } executor.shutdown(); // 关闭线程池 ``` 4. **使用Future和Callable** `Callable`接口类似于`Runnable`,但其`call...

    线程池核心组件源码剖析.docx

    2. **ExecutorService接口**:继承自Executor接口,增加了管理和控制线程池的功能,如`submit()`用于提交任务,`shutdown()`用于关闭线程池,`shutdownNow()`用于尝试停止所有正在执行的任务等。 3. **...

    Java Executor 框架学习总结

    这个框架的核心是 `Executor` 接口,它定义了一个单一的方法 `execute()`,用于提交 `Runnable` 或 `Callable` 任务。 在传统的并发编程中,我们通常会直接使用 `Thread` 类来创建和启动线程,如 `...

    Java并发框架:Executor API详解

    - **ExecutorService**: Executor的一个子接口,增加了管理和控制线程池的方法,如`shutdown()`和`submit()`。 - **Thread Pool**: 线程池是一种线程复用机制,可以预先创建一定数量的线程,当任务到来时,从池中...

    java基础知识之hadoop源码阅读必备(一).docx

    然后,通过`ExecutorService`的`submit()`方法提交这个任务,它会在新的线程中运行。这种方式不会返回结果,适用于无需等待任务完成的情况。 示例代码: ```java ExecutorService executor = Executors....

Global site tag (gtag.js) - Google Analytics