Detailed explanation of executor, executorservice and ThreadPoolExecutor in Java

Detailed explanation of executor, executorservice and ThreadPoolExecutor in Java

1.Excutor

The source code is very simple. There is only one execute (runnable command) callback interface

Execute the submitted runnable task object. This interface provides a method to separate task Submission from the mechanism of how each task will run (including details of thread usage, scheduling, etc.). It is common to use executor instead of explicitly creating threads. For example, instead of calling new thread (new (runnabletask()). Start() for each task in a set of tasks, you might use the following method:

However, the executor interface does not strictly require asynchronous execution. In the simplest case, the executor can immediately run the submitted task in the caller's thread:

More commonly, the task is executed in a thread that is not the caller's thread. The following executor will generate a new thread for each task.

Many executor implementations impose certain restrictions on how and when tasks are scheduled. The following execution procedure keeps the task submission continuous with the second execution procedure, which illustrates a composite execution procedure.

2. Excutorservice interface

Executorservice provides methods to manage termination and generate future for tracking the execution of one or more asynchronous tasks. Executorservice can be closed, which will cause it to reject new tasks. Two methods are provided to close executorservice. The shutdown () method allows the execution of previously submitted tasks before termination, while the shutdown now () method prevents waiting for the start of the task and attempts to stop the currently executing task. After termination, the executor has no task executing or waiting for execution, and cannot submit a new task. Unused executorservices should be closed to allow recycling of their resources.

The submit method extends the basic method executor. Execute (Java. Lang. runnable) by creating and returning a future that can be used to cancel execution and / or wait for completion. Methods invokeany and invokeall are the most common forms of batch execution. They execute task collection and wait for at least one or all tasks to complete (you can use the executorcompletionservice class to write custom variants of these methods). The executors class provides a convenient factory method for creating executorservice. Note 1: it only has a direct implementation class ThreadPoolExecutor and an indirect implementation class scheduledthreadpoolexecutor. For more information about ThreadPoolExecutor, please refer to ThreadPoolExecutor. For more information about scheduledthreadpoolexecutor, please refer to scheduledthreadpoolexecutor

Usage example

The following gives a simple structure of a network service, where the threads in the thread pool are used as incoming requests. It uses pre configured

The following method closes the executorservice in two phases. In the first stage, call shutdown to reject the incoming task. After 60 seconds, call shutdown now (if necessary) to cancel all remaining tasks before the task is completed:

Memory consistency effect: the operations before submitting the runnable or callable task to the executorservice in the thread happen before all the operations extracted by the task,

The latter, in turn, happens before the results obtained through future. Get().

Main functions:

void shutdown()

Start a close command, no longer accept new tasks, and close when all submitted tasks are completed. If closed, the call has no other effect.

Thrown: SecurityException - if the security manager exists and closes, the executorservice may operate on some threads that the caller is not allowed to modify (because it does not maintain runtimepermission ("modifythread")), or the security manager's checkAccess method denies access.

List<Runnable> shutdownNow()

An attempt was made to stop all active tasks being executed, suspend processing of tasks waiting, and return to the list of tasks waiting to be executed.

There is no guarantee that you can stop the activity you are working on and perform the task, but you will try your best. For example, a typical implementation is cancelled through thread. Interrupt(), so any task that fails to respond to an interrupt may never be terminated.

Return: list of tasks that have never started execution throw: SecurityException - if the security manager exists and is closed, the executorservice may operate on some threads that do not allow the caller to modify (because it does not maintain runtimepermission ("modifythread"), or the security manager's checkAccess method denies access.

Note 1: it returns a list of tasks waiting to be executed. Note 2: there is no guarantee that you can stop the activity you are working on and perform the task, but you will try your best. For example, cancel by thread. Interrupt(),

Therefore, any task that fails to respond to an interrupt may never be terminated. boolean isShutdown()

Returns true if the executor is closed. Return: returns true Boolean isterminated() if the executor has been closed. Returns true if all tasks have been completed after closing. Note that isterminated is never true unless shutdown or shutdown now is called first. Return: if all tasks have been completed after the shutdown, return true Boolean awaittermination (long timeout, timeunit) throws interruptedexception wait (block) until the shutdown or the longest waiting time or interruption occurs. Parameters: timeout - the longest waiting time unit - the time unit of the timeout parameter. Return: return true if the execution program terminates; If the timeout period before termination is full, return false. Throw out: interruptedexception - if an interrupt occurs while waiting. Note 1: return true if this executable terminates (closes); If the timeout period before termination expires, false < T > Future < T > submit (callable < T > task) is returned. A task with a return value is submitted for execution, and a future representing the pending results of the task is returned. The get method of the future will return the result of the task upon successful completion. If you want to block the waiting of the task immediately, you can use result = exec. Submit (acallable). Get(); Structure of form. Note: executors class includes a set of methods that can convert some other common objects similar to closures. For example, convert privilegedaction to callable form, so that they can be submitted. Parameters: Task - task to be submitted return: indicates the future of the task waiting to be completed. Throw: rejectedexecutionexception - if the task cannot be scheduled to execute NullPointerException - if the task is null

Note: for the use of submit and callable, please refer to returning results using callable

<T> Future<T> submit(Runnable task,T result)

Submit a runnable task for execution and return a future representing the task. The get method of the future will return the given result upon successful completion.

Parameters: Task - result of the task to be submitted - returned result: future throw indicating that the task is waiting to be completed: rejectedexecutionexception - if the task cannot be scheduled to execute NullPointerException - if the task is null note: for the use of submit, please refer to callable

Future<?> submit(Runnable task)

Submit a runnable task for execution and return a future representing the task. The get method of the future will return null on successful completion. Parameters: Task - return of the task to be submitted: indicates the future of the task waiting to be completed. Throw out: rejectedexecutionexception - if the task cannot be scheduled to execute NullPointerException - if the task is null. Note: for the use of submit, see returning results using callable

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException

Execute the given task. When all tasks are completed, return the future list that maintains the task status and results. The future. Isdone() of all elements of the returned list is true. Note that completed tasks can be terminated normally or by throwing exceptions. If the given collection is modified while this operation is in progress, the result of this method is uncertain. Parameter: tasks - task collection return: indicates the future list of tasks. The order of the list is the same as that generated by the iterator of the given task list. Each task has been completed. Throw: interruptedexception - if an interrupt occurs while waiting, cancel the unfinished task in this case. NullPointerException - if the task or any of its elements is null rejectedexecutionexception - if all tasks cannot be scheduled for execution note 1: this method will block until all tasks are completed.

Execute a given task. When all tasks are completed or the timeout period expires (whichever occurs first), return the future list that maintains the task status and results. The future. Isdone() of all elements of the returned list is true. Once returned, the unfinished task is cancelled. Note that completed tasks can be terminated normally or by throwing exceptions. If the given collection is modified while this operation is in progress, the result of this method is uncertain.

Parameters: tasks - task collection timeout - maximum waiting time unit - time unit of timeout parameter return: represents the future list of tasks, and the order of the list is the same as that generated by the iterator of the given task list. If the operation does not time out, all tasks have been completed. If you do time out, some tasks have not been completed. Throw: interruptedexception - if an interrupt occurs while waiting, in this case, cancel the uncompleted task NullPointerException - if the task or any of its elements or units is null rejectedexecutionexception - if all tasks cannot be scheduled for execution. Note 1: this method will block until all tasks are completed or timeout. Note 2: if it does time out, some tasks have not been completed. [then these unfinished tasks should be cancelled by the system]< T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException

Execute a given task. If a task has been successfully completed (that is, no exception has been thrown), the result is returned. Once normal or abnormal returns, the unfinished task is cancelled.

If the given collection is modified while this operation is in progress, the result of this method is uncertain. Parameters: tasks - task collection return: the result returned by a task is thrown: interruptedexception - if an interrupt occurs while waiting, NullPointerException - if the task or any of its elements is null, illegalargumentexception - if the task is empty, executionexception - if no task completes successfully, rejectedexecutionexception - if the task cannot be scheduled Execution note 1: this method will block until a task is completed. Note 2: once normal or abnormal returns, the unfinished task will be cancelled

Execute the given task. If a task has been successfully completed before the expiration of the given timeout period (that is, no exception is thrown), the result is returned. Once normal or abnormal returns, the unfinished task is cancelled. If the given collection is modified while this operation is in progress, the result of this method is uncertain.

Parameters: tasks - task collection timeout - maximum waiting time unit - time unit of timeout parameter return: the result returned by a task is thrown: interruptedexception - if an interrupt occurs while waiting, NullPointerException - if the task or any of its elements or units is null, timeoutexception - if the given timeout before all tasks are successfully completed Full executionexception - if no task completes successfully rejectedexecutionexception - if the task cannot be scheduled for execution note 1: the method will block until a task completes. Note 2: once normal or abnormal returns, the unfinished task will be cancelled

3.ThreadPoolExecutor

ThreadPoolExecutor is an implementation class of executorservice. It uses one of several possible pool threads to execute each submitted task. It is usually configured using the executors factory method. Thread pools can solve two different problems: because they reduce the overhead of each task call, they can usually provide enhanced performance when executing a large number of asynchronous tasks, and can also provide methods to bind and manage resources, including the threads used when executing task sets. Each ThreadPoolExecutor also maintains some basic statistics, such as the number of tasks completed. To facilitate use across a large number of contexts, this class provides many adjustable parameters and extended hooks. However, it is strongly recommended that programmers use the more convenient executors factory methods executors. Newcachedthreadpool() (unbounded thread pool, which can be used for automatic thread recycling), executors. Newfixedthreadpool (int) (fixed size thread pool) and executors. Newsinglethreadexecution() (single background thread), which have predefined settings for most usage scenarios. Otherwise, when manually configuring and adjusting this class, use the following guidelines: core and maximum pool size

ThreadPoolExecutor will automatically resize the pool based on the boundaries set by corepoolsize (see getcorepoolsize()) and maximumpoolsize (see getmaximumpoolsize()). When a new task is submitted in the method execute (Java. Lang. runnable), if the number of running threads is less than corepoolsize, a new thread is created to process the request, even if some threads are idle. If more threads are running than corepoolsize and less than maximumpoolsize, a new thread is created only when the queue is full. If you set the same corepoolsize and maximumpoolsize, a fixed size thread pool is created. If maximumpoolsize is set to a basic unbounded value (such as integer.max_value), the pool is allowed to accommodate any number of concurrent tasks. In most cases, the core and maximum pool sizes are set only based on the construction, but they can also be changed dynamically using setcorepoolsize (int) and setmaximumpoolsize (int). Note 1: when a new task is submitted, if the running core thread is less than corepoolsize, a new core thread is created. The core poolsize thread is not created at the beginning. Note 2: "if the number of running threads is more than corepoolsize but less than maximumpoolsize, a new thread will be created only when the queue is full." the core thread of on-demand construction is initially created and started by ThreadPoolExecutor only when a new task arrives, but you can also manually call the methods prestartcorethread() or prestartallcorethreads() to start the core thread in advance. If you construct a pool with a non empty queue, you may want to start the thread in advance. Note 1: the core thread is the core thread. Only when the current number of threads is less than or equal to the corepoolsize can the thread be called the core thread. Create a new thread create a new thread using threadfactory. Unless otherwise specified, use executors. Defaultthreadfactory() to create threads that are in the same ThreadGroup and have the same norm_ Priority priority and non daemon status. By providing different threadfactory, you can change the thread name, thread group, priority, daemon status, and so on. If threadfactory fails to create a thread when null is returned from newthread, the executor will continue to run but cannot perform any tasks. Note 1: the threadfactory for creating threads can be specified. By default, executors. Defaultthreadfactory() is used to create threads. All threads are in a ThreadGroup. Keep alive time if there are currently more threads in the pool than corepoolsize, these extra threads will terminate when their idle time exceeds keepalivetime (see getkeepalivetime (Java. Util. Concurrent. Timeunit)). This provides a way to reduce resource consumption when the pool is inactive. If the pool later becomes more active, you can create new threads. You can also change this parameter dynamically using the method setkeepalivetime (long, Java. Util. Concurrent. Timeunit). If the value is set to long.max_ If value timeunit.nanoseconds is used, idle threads will not be recycled until ThreadPoolExecutor is terminated. By default, the keep alive policy applies only when there are more threads than corepoolsizethread. However, the allowcorethreadtimeout (Boolean) method can also apply this timeout policy to the core thread as long as the keepalivetime value is not 0. Note 1: setkeepalivetime (long, Java. Util. Concurrent. Timeunit) is used to set the longest active time of an idle thread, that is, if the idle time exceeds the set value, stop the thread and recycle the thread. By default, this policy is only useful for non kernel threads (that is, the current number of threads is greater than the corepoolsize). You can call the allowcorethreadtimeout (Boolean) method to expand this timeout policy to core threads. Note 2: if the value is set to long.max_ If value timeunit.nanoseconds is used, idle threads will not be recycled until ThreadPoolExecutor is terminated. Queueall blockingqueues can be used to transfer and hold submitted tasks. You can use this queue to interact with the pool size: * if fewer threads are running than corepoolsize, the executor always prefers to add new threads instead of queuing* If more threads are running than or equal to corepoolsize, the executor always prefers to queue requests instead of adding new threads* If the request cannot be queued, a new thread is created unless the creation of this thread exceeds the maximumpoolsize, in which case the task will be rejected. There are three general queuing strategies: 1. Direct submission. The default option for work queues is synchronous queue, which submits tasks directly to threads without holding them. Here, if there is no thread available to run the task immediately, the attempt to queue the task will fail, so a new thread will be constructed. This policy avoids locks when processing request sets that may have internal dependencies. Direct submission usually requires unbounded maximumpoolsizes to avoid rejecting newly submitted tasks. This strategy allows threads to grow unbounded when commands arrive continuously more than the average number that the queue can handle. Note 1: this policy allows threads to grow unbounded. 2. Unbounded queue. Using unbounded queues (for example, linkedblockingqueue without predefined capacity) will cause new tasks to wait in the queue when all corepoolsize threads are busy. In this way, the created thread will not exceed the corepoolsize. (therefore, the value of maximumpoolsize is invalid.) when each task is completely independent of other tasks, that is, task execution does not affect each other, it is suitable to use unbounded queue; For example, in a web page server. This kind of queuing can be used to handle transient burst requests. When commands arrive continuously more than the average number that the queue can handle, this strategy allows the queue to grow indefinitely. Note 1: this policy allows unlimited queue growth. 3. Bounded queue. When using limited maximumpoolsizes, bounded queues, such as arrayblockingqueue, help prevent resource exhaustion, but may be difficult to adjust and control. Queue size and maximum pool size may need to compromise each other: using large queues and small pools can minimize CPU utilization, operating system resources and context switching overhead, but may lead to manual throughput reduction. If tasks block frequently (for example, if they are I / O boundaries), the system may schedule more threads than you allow. Using a small queue usually requires a large pool size and high CPU utilization, but it may encounter unacceptable scheduling overhead, which will also reduce throughput. Rejected task when the executor has been closed, or the executor has used the limited boundary for the maximum thread and work queue capacity and has been saturated, the new task submitted in the method execute (Java. Lang. runnable) will be rejected. In both cases, the execute method will call its rejectedexecutionhandler. Rejectedexecution (Java. Lang. runnable,

Java. Util. Concurrent. ThreadPoolExecutor) method.

Four predefined handler policies are provided below:

1. In the default threadpoolexecutor.abortpolicy, if the handler is rejected, the runtime rejectedexecutionexception will be thrown. 2. In threadpoolexecutor.callerrunspolicy, the thread calls the execute itself that runs the task. This strategy provides a simple feedback control mechanism, which can slow down the submission speed of new tasks. 3. In threadpoolexecutor.discardpolicy, tasks that cannot be executed will be deleted. 4. In threadpoolexecutor.discardoldestpolicy, if the executing program has not been closed, the task at the head of the work queue will be deleted, and then the executing program will be retried (if it fails again, repeat this process). It is also possible to define and use other kinds of rejectedexecutionhandler classes, but this requires great care, especially when the policy is only used for specific capacity or queuing policies

Note 1: abortpolicy, callerrunspolicy, discardpolicy and discardoldestpolicy are all implementations of rejectedexecution. Of course, you can also define a rejectedexecution implementation yourself. The hook (hook) method provides protected rewritable beforeExecute (java.lang.Thread, java.lang.Runnable) and afterExecute (java.lang.Runnable, java.lang.Throwable) methods. These two methods are invoked before and after each task is executed. They can be used to manipulate the execution environment; For example, reinitialize ThreadLocal, collect statistics, or add log entries. In addition, you can override the method terminated () to perform all special processing that needs to be completed after the executor is completely terminated. If the hook or callback method throws an exception, all threads of ThreadPoolExecutor will fail in turn and terminate suddenly.

The queue maintenance method getqueue () allows access to work queues for monitoring and debugging purposes. The use of this method for any other purpose is strongly opposed. Remove (Java. Lang. runnable) and purge () can be used to help with storage reclamation when canceling a large number of queued tasks. Note 1: if the task is cancelled, the ThreadPoolExecutor should be able to store and recycle itself. Cancelled tasks will not be executed again, but they may accumulate in the work queue until the worker thread actively removes them. Externally, remove (Java. Lang. runnable) and purge () can be used to remove them from the queue immediately. Termination if ThreadPoolExecutor does not have any references in the program and there are no active threads, it will not automatically shut down. If you want to ensure that threads are recycled (even if the user forgets to call shutdown ()), you must schedule the final termination of unused threads: set the appropriate keep alive time, use the lower boundary of 0 core threads, and / or set allowcorethreadtimeout (Boolean). Extended example. Most extensions of this class can override one or more protected hook methods. For example, the following is a subclass that adds a simple pause / resume function:

Please refer to executorservice for its use

Primary constructor:

Create a new ThreadPoolExecutor with the given initial parameters, the default thread factory and the rejected execution handler. Using one of the executors factory methods is much more convenient than using this general construction method. Parameter: corepoolsize - number of threads saved in the pool, including idle threads. Maximumpoolsize - the maximum number of threads allowed in the pool. Keepalivetime - when the number of threads is greater than the core, this is the maximum time for redundant idle threads to wait for new tasks before termination. Unit - the time unit of the keepalivetime parameter. Workqueue - the queue used to hold the task before execution. This queue holds only runnable tasks submitted by the execute method. Throw: illegalargumentexception - if corepoolsize or keepalivetime is less than 0, or maximumpoolsize is less than or equal to 0, or corepoolsize is greater than maximumpoolsize. NullPointerException - if workqueue is null

Create a new ThreadPoolExecutor with the given initial parameters and the default rejected execution handler.

Parameter: corepoolsize - number of threads saved in the pool, including idle threads. Maximumpoolsize - the maximum number of threads allowed in the pool. Keepalivetime - when the number of threads is greater than the core, this is the maximum time for redundant idle threads to wait for new tasks before termination. Unit - the time unit of the keepalivetime parameter. Workqueue - the queue used to hold the task before execution. This queue holds only runnable tasks submitted by the execute method. Threadfactory - the factory used by the executor to create a new thread. Throw: illegalargumentexception - if corepoolsize or keepalivetime is less than 0, or maximumpoolsize is less than or equal to 0, or corepoolsize is greater than maximumpoolsize. NullPointerException - if workqueue or threadfactory is null.

Create a new ThreadPoolExecutor with the given initial parameters and the default thread factory.

Parameter: corepoolsize - number of threads saved in the pool, including idle threads. Maximumpoolsize - the maximum number of threads allowed in the pool. Keepalivetime - when the number of threads is greater than the core, this is the maximum time for redundant idle threads to wait for new tasks before termination. Unit - the time unit of the keepalivetime parameter. Workqueue - the queue used to hold the task before execution. This queue consists only of runnable tasks submitted by the keep execute method. Handler - the handler used when execution is blocked due to out of thread range and queue capacity. Throw: illegalargumentexception - if corepoolsize or keepalivetime is less than 0, or maximumpoolsize is less than or equal to 0, or corepoolsize is greater than maximumpoolsize.

Main member function

public void execute(Runnable command)

Perform a given task at some time in the future. You can perform this task in a new thread or in an existing pool thread. If the task cannot be submitted for execution, or because the executor is closed, or because its capacity has been reached, the task is processed by the current rejectedexecutionhandler. Parameter: Command - task to be executed. Throw: rejectedexecutionexception - if the task to be executed cannot be received, it is up to rejectedexecutionhandler to decide whether to throw rejectedexecutionexception NullPointerException - if the command is null

public void shutdown()

Initiate an orderly shutdown in the order of executing the submitted tasks in the past, but do not accept new tasks. If closed, the call has no other effect. Throw: SecurityException - if the security manager exists and closes this executorservice, it may operate on some threads that the caller is not allowed to modify (because it does not have runtimepermission ("modifythread")), or the security manager's checkAccess method denies access. Public list < runnable > shutdownnow() attempts to stop all active execution tasks, pause the processing of waiting tasks, and return the list of waiting tasks. Empty (remove) these tasks from the task queue returned from this method. There is no guarantee that you can stop the activity you are working on and perform the task, but you will try your best. This implementation cancels the task through thread. Interrupt(), so any task that cannot respond to an interrupt may never be terminated. Return: a list of tasks that have never been started. Throw: SecurityException - if the security manager exists and closes this executorservice, it may operate on some threads that the caller is not allowed to modify (because it does not have runtimepermission ("modifythread")), or the security manager's checkAccess method denies access.

public int prestartAllCoreThreads()

Start all core threads and leave them idle waiting for work. This operation overrides the default start core thread policy only when a new task is executed. Return: number of threads started

public boolean allowscoreThreadTimeOut()

If this pool allows the core thread to time out and terminate, and if no task arrives within the keepalive time, and the new task is being replaced when it arrives (if necessary), return true. When true is returned, the same keep alive policy that applies to non core threads also applies to core threads. When false (the default value) is returned, the core thread will not terminate because there is no incoming task. Return: returns true if the core thread is allowed to timeout; Otherwise, false is returned

public void allowCoreThreadTimeOut(boolean value)

If no task arrives within the keep alive time and the new task is being replaced when it arrives (if necessary), set the policy to control whether the core thread times out or terminates. When it is false (the default), the core thread will never abort because there is no incoming task. When true, the same keep alive policy that applies to non core threads also applies to core threads. To avoid continuous thread replacement, the keep alive time must be greater than 0 when set to true. This method should usually be called before active use of the pool. Parameter: value - true if timeout is expected; Otherwise, it is false and thrown: illegalargumentexception - if value is true and the current keep alive time is not greater than 0.

public boolean remove(Runnable task)

Remove this task from the internal queue of the executor, if it exists, so that it will no longer run if it has not already started. This method can be used as part of a cancellation scheme. It may not be able to remove tasks that have been converted to other forms before being placed on the internal queue. For example, a task entered using submit may be transformed into maintaining the future state. However, in this case, the purge () method can be used to remove those future that have been cancelled. Parameter: Task - task to be removed return: returns true if the task has been removed

public void purge()

Attempt to remove all cancelled future tasks from the work queue. This method can be used as a storage reclamation operation and has no impact on the function. Cancelled tasks do not execute again, but they may accumulate in the work queue until the worker thread actively removes them. Calling this method will attempt to remove them immediately. However, if other threads intervene, this method will fail to remove the task. Of course, it also implements the submit series interface of executorservice

Thank you for reading, hope to help you, thank you for your support to this site!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>