Understanding and use of ExecutorService

The understanding and use of ExecutorService
Translate November 20, 2013 19:36:47 67981 The
interface java.util.concurrent.ExecutorService expresses the mechanism of asynchronous execution, and allows tasks to be executed in the background. An ExecutorService instance is therefore very much like a thread pool. In fact, the implementation of ExecutorService in the java.util.concurrent package is an implementation of a thread pool.
ExecutorService Example

Here is a simple example of an ExectorService implemented in Java:
[java] view plain copy
ExecutorService executorService = Executors.newFixedThreadPool(10); 
 
executorService.execute(new Runnable() { 
    public void run() { 
        System. out.println("Asynchronous task"); 
    } 
}); 
 
executorService.shutdown(); 
First create an ExecutorService using the newFixedThreadPool() factory method. The above code creates a thread pool that can hold 10 thread tasks. Second, pass an implementation of the asynchronous Runnable interface to the execute() method, which will cause a thread in the ExecutorService to execute the Runnable thread. A schematic diagram of a thread's ExecutorService that delegates tasks to execute asynchronously is shown under
Task Delegation . Once a thread delegates a task to an ExecutorService, the thread continues to perform other tasks unrelated to running the task. Implementation of ExecutorService Since ExecutorService is just an interface, if you need to use it a lot, you need to provide an implementation of the interface. The ExecutorService interface has the following implementation classes in the java.util.concurrent package: ThreadPoolExecutor ScheduledThreadPoolExecutor Create an ExecutorService You can create an ExecutorService according to your own needs, or you can use the Executors factory method to create an ExecutorService instance. Here are a few examples of creating an ExecutorService: [java] view plain copy ExecutorService executorService1 = Executors.newSingleThreadExecutor(); 












ExecutorService executorService2 = Executors.newFixedThreadPool(10); 
ExecutorService executorService3 = Executors.newScheduledThreadPool(10);  How
to use ExecutorService

There are several different ways to delegate tasks to an ExecutorService:
[java] view plain copy
execute(Runnable) 
submit(Runnable) 
submit(Callable) 
invokeAny(...) 
invokeAll(...) 
I'll take a look at each method in what follows.
The execute(Runnable)

method execute(Runnable) receives a java.lang.Runnable object as a parameter and executes it asynchronously. The following is an example of using ExecutorService to execute Runnable:
[java] view plain copy
ExecutorService executorService = Executors.newSingleThreadExecutor(); 
 
executorService.execute(new Runnable() { 
    public void run() { 
        System.out.println("Asynchronous task"); 
    } 
}); 
     
executorService.shutdown(); 
There is no way to get the result after executing Runnable in this way. If you want to get the return value after running, you must use the receiving Callable The execute() method with parameters, the latter will be mentioned below.
The submit(Runnable)

method submit(Runnable) also accepts a Runnable implementation as a parameter, but returns a Future object. This Future object can be used to determine whether the Runnable has finished executing. The following is an example of the submit() method of an ExecutorService:
[java] view plain copy
Future future = executorService.submit(new Runnable() { 
    public void run() { 
        System.out.println("Asynchronous task"); 
    } 
}); 
//If the task finishes executing, return null 
System.out.println("future.get()=" + future.get()); 
submit(Callable)

The method submit(Callable) is similar to the method submit(Runnable), but the difference is that they accept different parameter types. Instances of Callable are similar to instances of Runnable, but the callable's call() method can return a result. The method Runnable.run() cannot return a result.

The return value of Callable can be obtained from the Future object returned by the method submit(Callable). The following is an example of an ExecutorService Callable:
[java] view plain copy
Future future = executorService.submit(new Callable(){ 
    public Object call() throws Exception { 
        System.out.println("Asynchronous Callable"); 
        return " Callable Result"; 
    } 
}); 
 
System.out.println("future.get() = " + future.get()); 

The above sample code will output the following result:
[java] view plain copy
ExecutorService executorService = Executors. newSingleThreadExecutor(); 
 
Set<Callable<String>> callables = new HashSet<Callable<String>>(); 
 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
        return "Task 1"; 
    } 
}); 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
        return "Task 2"; 
    } 
}); 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
        return "Task 3"; 
    } 
}); 
 
String result = executorService.invokeAny(callables); 
 
System.out.println("result = " + result); 
 
executorService.shutdown(); 
inVokeAny()

The method invokeAny() receives a collection of Callable objects as a parameter. Calling this method will not return a Future object, but will return the result of a Callable object in the collection, and there is no guarantee which Callable the returned result will be after the call, only that it is one of these Callables whose execution ends. .
If a task finishes running or throws an exception, the method cancels the execution of other Callables.
Here is an example:
[java] view plain copy
ExecutorService executorService = Executors.newSingleThreadExecutor(); 
 
Set<Callable<String>> callables = new HashSet<Callable<String>>(); 
 
callables.add(new Callable<String >() { 
    public String call() throws Exception { 
        return "Task 1"; 
    } 
}); 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
        return "Task 2"; 
    } 
} ); 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
        return "Task 3"; 
    } 
}); 
 
String result = executorService.invokeAny(callables); 
 
System.out.println("result = " + result); 
 
executorService.shutdown(); 
The above sample code will print out the return result of a Callable in the given collection. I've tried running it a few times and the results are changing. Sometimes the result is "Task 1", sometimes "Task 2", etc.
The invokeAll()
method invokeAll() will call all Callable objects in the parameter set and return a set containing Future objects. You can manage the execution result of each Callable through the returned set.
It should be noted that the task may end due to an exception, so it may not really run successfully. But we have no way of knowing this difference through the Future object.
The following is a code sample:
[java] view plain copy
ExecutorService executorService = Executors.newSingleThreadExecutor(); 
 
Set<Callable<String>> callables = new HashSet<Callable<String>>(); 
 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
        return "Task 1"; 
    } 
}); 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
        return "Task 2"; 
    } 
}); 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
        return "Task 3"; 
    } 
}); 
 
String result = executorService.invokeAny(callables); 
 
System.out.println("result = " + result); 
 
executorService.shutdown(); 
Closing the ExecuteService service

After using the ExecutorService, we should close it, so as to ensure that the thread will not continue to run.
For example, if your program is started via the main() method, and the main thread exits your program, the program will continue to run if you still have an active ExecutorService in your program. Active threads that exist in the ExecutorService prevent the Java Virtual Machine from shutting down.
In order to shut down the thread in the ExecutorService, you need to call the shutdown() method. The ExecutorService will not close immediately, but will no longer receive new tasks. Once all threads finish executing the current task, the ExecutorServie will really close. All tasks submitted to the ExecutorService before the shutdown() method is called will be executed.
If you wish to shut down the ExecutorService immediately, you can call the shutdownNow() method. This method will try to close all running tasks immediately, and skip any tasks that have been submitted but not yet running. But for the task being executed, there is no guarantee that it can be successfully closed, it is possible that they are actually closed, or it may be executed until the end of the task. This is a best attempt.
The English original link of this article: http://tutorials.jenkov.com/java-util-concurrent/executorservice.html#executorservice-example, the Chinese translation is first published in the open source Chinese community http://my.oschina.net/bairrfhoinn/blog/177639 , please indicate the original source when reprinting.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326603000&siteId=291194637