The execute and submit methods of ExecutorService

http://www.cnblogs.com/sunxucool/p/3156898.htmlThree


differences:

1. The received parameters are different

2. Submit has a return value, while execute does not have

Method submit extends base method Executor.execute by creating and returning a Future that can be used to cancel execution and/or wait for completion.

An example of using a return value, for example, I have many tasks for validation, I want all tasks to be executed, and then each task tells me its The execution result, whether it succeeded or failed, and if it failed, what is the reason. Then I can combine all the reasons for the failure and send it to the caller.

Personally, I think cancel execution is not very useful, and it is rarely necessary to cancel execution.

And the biggest use should be the second point.

3. submit is convenient for Exception handling

There is a difference when looking at exception handling. If your tasks throws an exception and if it was submitted with execute this exception will go to the uncaught exception handler (when you don't have provided one explicitly, the default one will just print the stack trace to System.err). If you submitted the task with submit any thrown exception, checked or not, is then part of the task's return status. For a task that was submitted with submit and that terminates with an exception, the Future. get will rethrow this exception, wrapped in an ExecutionException.
This means that if you throw a checked or unchecked exception in your task, and you want the outside caller to perceive these exceptions and deal with them in a timely manner, then you need to Use submit, by catching the exception thrown by Future.get.



For example, I have many tasks that update various data, and I hope that if one of the tasks fails, the other tasks do not need to be executed. Then I need to catch the exception thrown by Future.get, and then terminate the execution of other tasks. The code is as follows:

There is a very good article "Java5 Concurrency Learning" on 51cto (http://lavasoft.blog.51cto.com/62575/115112), the following code is modified based on it.



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 ExecutorServiceTest { 
    public static void main(String[] args) { 
        ExecutorService executorService = Executors.newCachedThreadPool(); 
        List<Future<String>> resultList = new ArrayList<Future<String>>(); 
 
        // create 10 tasks and execute them 
        for (int i = 0; i < 10; i++) { 
            // Use ExecutorService to execute Callable type task and save the result in future variable 
            Future<String> future = executorService.submit(new TaskWithResult(i)); 
            / / Store the task execution result in a List 
            resultList.add(future); 
        } 
        executorService.shutdown(); 
 
        // Traverse the result of the task 
        for (Future<String> fs : resultList) { 
            try { 
                System.out.println(fs. get()); // print the execution result of each thread (task) 
            } 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; 
    } 
 
    /**
     * The specific process of the task, once the task is passed To the submit method of ExecutorService, the method is automatically executed on a thread.
     * 
     * @return
     * @throws Exception
     */ 
    public String call() throws Exception { 
        System.out.println("call() method is automatically called, work!!! " + Thread.currentThread().getName()) ; 
        if (new Random().nextBoolean()) 
            throw new TaskException("Meet error in task." + Thread.currentThread().getName()); 
        // a simulated time-consuming operation 
        for (int i = 999999999; i > 0; i--) 
            ; 
        return "call () method is automatically called, the result of the task is: " + id + " " + Thread.currentThread().getName(); 
    } 

 
class TaskException extends Exception { 
    public TaskException(String message) { 
        super(message); 
    } 


The result of the execution is similar to: The

call() method is automatically called, work! ! ! The pool-1-thread-1 
call() method is automatically called, work! ! ! The pool-1-thread-2 
call() method is automatically called, work! ! ! The pool-1-thread-3 
call() method is automatically called, work! ! ! pool-1-thread-5 
The call() method is automatically called, work! ! ! The pool-1-thread-7 
call() method is automatically called, work! ! ! The pool-1-thread-4 
call() method is automatically called, work! ! ! The pool-1-thread-6 
call() method is automatically called, work! ! ! The pool-1-thread-7 
call() method is automatically called, work! ! ! The pool-1-thread-5 
call() method is automatically called, work! ! ! pool-1-thread-8 
call() method is automatically called, the result of the task is: 0 pool-1-thread-1 
call() method is automatically called, the result of the task is: 1 pool-1-thread-2 
java .util.concurrent.ExecutionException: com.cicc.pts.TaskException: Meet error in task.pool-1-thread-3 
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) 
    at java.util .concurrent.FutureTask.get(FutureTask.java:83) 
    at com.cicc.pts.ExecutorServiceTest.main(ExecutorServiceTest.java:29) 
Caused by: com.cicc.pts.TaskException: Meet error in task.pool-1-thread-3 
    at com.cicc.pts.TaskWithResult.call(ExecutorServiceTest.java:57) 
    at com.cicc.pts.TaskWithResult.call(ExecutorServiceTest.java:1) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:619) 
可以看见一旦某个task出错,其它的task就停止执行。

From: http://blog.csdn.net/peachpi/article/details/6771946

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326357263&siteId=291194637