引用:http://blog.csdn.net/suifeng3051/article/details/49443835
本篇主要涉及到的是java.util.concurrent包中的ExecutorService。ExecutorService就是Java中对线程池的实现。
I. Introduction of Executorservice
Executorservice is an interface defined in Java for the thread pool, which java.util.concurrent
defines the methods associated with background task execution in this interface:
The Java API has two implementations for the Executorservice interface, so these are the Java thread Pool implementation classes (Learn more about these two implementation classes, click here):
1. ThreadPoolExecutor2. ScheduledThreadPoolExecutor
In addition, Executorservice also inherited the Executor
interface (note the executor interface and executors factory Class), this interface has only one execute()
method, and finally we look at the entire inheritance tree:
Second, the creation of Executorservice
Creating an instance of what Executorservice (that is, the thread pool) requires G to be based on a specific scenario, but Java provides us with one Executors工厂类
that can help us easily create various types of executorservice thread pools, Executors altogether can create the following four types of thread pools:
1. newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。2. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。3. newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。4. newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
Note: Executors is just a factory class, and all of its methods return ThreadPoolExecutor
instances of ScheduledThreadPoolExecutor
these two classes.
Third, the use of Executorservice
ExecutorService executorService = Executors.newFixedThreadPool(10);executorService.execute(new Runnable() {public void run() { System.out.println("Asynchronous task");}});executorService.shutdown();
Iv. implementation of the Executorservice
Executorservice has the following execution methods:
- execute(Runnable)- submit(Runnable)- submit(Callable)- invokeAny(...)- invokeAll(...)
4.1 Execute (Runnable)
This method takes a runnable instance and executes asynchronously, see the following example:
ExecutorService executorService = Executors.newSingleThreadExecutor();executorService.execute(new Runnable() {public void run() { System.out.println("Asynchronous task");}});executorService.shutdown();
One problem with this approach is that there is no way to know the outcome of a task's execution. If we want to get the task execution result, we can pass in an instance of callable (described below).
4.2 Submit (Runnable)
submit(Runnable)
And the execute(Runnable)
difference is that the former can return a future object, through the return of the future object, we can check whether the submitted task is completed, see the following examples of execution:
Future future = executorService.submit(new Runnable() {public void run() { System.out.println("Asynchronous task");}});future.get(); //returns null if the task has finished correctly.
If the task execution completes, the future.get()
method returns a null. Note that the Future.get () method can cause blocking.
4.3 Submit (callable)
submit(Callable)
and submit(Runnable)
similar, will return a future object, but in addition, submit (callable) received is a callable implementation, callable interface call()
method has a return value, you can return the results of the task execution, The method in the Runnable interface run()
is void
, and there is no return value. Take a look at the following example:
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());
If the task execution completes, the Future.get () method returns the result of the execution of the callable task. Note that the Future.get () method can cause blocking.
4.4 Invokeany (...)
invokeAny(...)
The method receives a collection of callable, which does not return to the future, but returns the result of the execution of one of the tasks in all callable tasks. This method also does not guarantee which task will return the result of the execution, anyway it is one of them. Take a look at the following example:
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();
You can try to execute the above code, each execution will return a result, and the returned result is a change, may return "Task2" is also "Task1" or other.
4.5 InvokeAll (...)
invokeAll(...)
And invokeAny(...)
similar also receives a callable collection, but the former executes will return a future list, which corresponds to each callable task after the execution of the next object. Here's an example of this:
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";}});List<Future<String>> futures = executorService.invokeAll(callables);for(Future<String> future : futures){System.out.println("future.get = " + future.get());}executorService.shutdown();
V. Closure of the Executorservice
It should be closed after we have finished the Executorservice, otherwise the thread inside it will remain in the running state.
For example, if the application is started by the main () method, after this main () exit, if the Executorservice in the application is not closed, the application will run. This occurs because a thread running in Executorservice prevents the JVM from shutting down.
If you want to close the thread executing in Executorservice, we can call the ExecutorService.shutdown()
method. After calling the shutdown () method, Executorservice does not close immediately, but it no longer receives the new task until all the current threads have finished executing and all tasks committed before shutdown () are executed.
If we want to close executorservice immediately, we can call the ExecutorService.shutdownNow()
method. This action skips all the tasks that are being performed and the tasks that have not been committed yet. However, it does not guarantee any of the tasks that are being performed, it is possible that they will be stopped, or it may be done.
For a more detailed introduction to the Java thread Pool class Threadpoolexecutor, Scheduledthreadpoolexecutor, and Executors factory classes, click here
Java thread pool Executorservice