I. Why use thread pool 1. Reduce the number of times that threads are created and destroyed, and each worker thread can be reused to perform multiple tasks. 2. You can adjust the number of threads in the thread pool according to the endurance of the system, prevent the server from being exhausted because it consumes too much memory (approximately 1MB of memory per thread, the more threads open, the more memory is consumed and the last crashes). The top interface of the thread pool in Java is executor, but strictly speaking, executor is not a thread pool, but a tool for executing threads. The real thread pool interface is executorservice. Two. Compare several important class Executorservice: A true thread pool interface. Scheduledexecutorservice: Can be similar to Timer/timertask to solve the problem that requires the task to be executed repeatedly. The default implementation of Threadpoolexecutor:executorservice. Scheduledthreadpoolexecutor: Inheriting Threadpoolexecutor's Scheduledexecutorservice interface implementation, the class implementation of periodic task scheduling.
1. Inheritance Relationship:Threadpoolexexutor inherited the Abstractexecutorservice Abstractexecutorservice realized the Executorservice Executorservice inherited executor.
2. Relationships between Threadpoolexecutor, Abstractexecutorservice, Executorservice and executor: Executor is a top-level interface, in which only one method execute (Runnable) is declared, the return value is void, the argument is of type Runnable, which can be understood by literal meaning and is used to perform the task passed in; Then the Executorservice interface inherits the executor interface and declares some methods: Submit, InvokeAll, Invokeany and shutdown, etc. Abstract class Abstractexecutorservice implements the Executorservice interface, which basically implements all the methods declared in Executorservice; Then Threadpoolexecutor inherits the class Abstractexecutorservice.
3. The four construction methods available in the Threadpoolexecutor class:public class Threadpoolexecutor extends Abstractexecutorservice { public threadpoolexecutor (int Corepoolsize,int Maximumpoolsize,long Keepalivetime,timeunit unit, blockingqueue<runnable> workQueue); public threadpoolexecutor (int Corepoolsize,int Maximumpoolsize,long Keepalivetime,timeunit unit, blockingqueue<runnable> workqueue,threadfactory threadfactory); Public threadpoolexecutor (int corepoolsize,int maximumpoolsize,long keepalivetime,timeunit unit, blockingqueue<runnable> WorkQueue, Rejectedexecutionhandler handler); public threadpoolexecutor (int corepoolsize,int maximumPoolSize , Long Keepalivetime,timeunit unit, blockingqueue<runnable> Workqueue,threadfActory Threadfactory,rejectedexecutionhandler handler);}
4. The meaning of each parameter:
corepoolsize: The size of the core pool, this parameter is very much related to the implementation principle of the thread pool described later. After the thread pool has been created, by default, there are no threads in the thread pools, instead of waiting for a task to be created to perform the task, unless the prestartallcorethreads () or Prestartcorethread () method is called. As you can see from the names of these 2 methods, the meaning of the pre-created thread is to create a corepoolsize thread or a thread before the task arrives. By default, after a thread pool has been created, the number of threads in the thread pools is 0, and when a task comes, a thread is created to perform the task, and when the number of threads in the thread pool reaches corepoolsize, the incoming task is placed in the cache queue;
maximumpoolsize: Thread pool Maximum number of threads, this parameter is also a very important parameter that represents the maximum number of threads that can be created in a thread pool
KeepAliveTime: Indicates the maximum length of time a thread will be terminated without a task execution. By default, KeepAliveTime only works if the number of threads in the thread pool is greater than corepoolsize, until the number of threads in the thread pool is not greater than corepoolsize, that is, when the number of threads in the thread pool is greater than corepoolsize. If a thread is idle for KeepAliveTime, it terminates until the number of threads in the thread pool does not exceed corepoolsize. However, if the Allowcorethreadtimeout (Boolean) method is called, the KeepAliveTime parameter also works when the number of threads in the thread pool is not greater than corepoolsize, until the number of threads in the thread pool is 0;
Unit: The time unit of the parameter KeepAliveTime, there are 7 kinds of values, there are 7 kinds of static properties in the Timeunit class: Timeunit.days; Days Timeunit.hours; Hour timeunit.minutes; Minutes Timeunit.seconds; Seconds timeunit.milliseconds; Ms Timeunit.microseconds; Subtle timeunit.nanoseconds; Na-Sec
WorkQueue: A blocking queue, which is used to store tasks waiting to be executed, and the selection of this parameter is also important, which can have a significant impact on the running process of the thread pool, in general, there are several options for blocking queues here Arrayblockingqueue: Bounded blocking queue based on array structure, sorting tasks by FIFO ; Linkedblockingquene: A list-based blocking queue that sorts tasks by FIFO, with throughput typically higher than Synchronousquene: A blocking queue that does not store elements, and each insert operation must wait for another thread to invoke the remove operation, or the insert operation In the blocking state, throughput is usually higher than arrayblockingquene; Priorityblockingquene: unbounded blocking queue with priority;
threadfactory: Thread factory, mainly used to create threads;
Handler: Represents the following four values for policies that are rejected when processing a task: Threadpoolexecutor.abortpolicy: Discards the task and throws the rejectedexecutionexception exception. Threadpoolexecutor.discardpolicy: Also discards the task, but does not throw an exception. Threadpoolexecutor.discardoldestpolicy: Discards the first task in the queue and then tries to perform the task again (repeat this process) Threadpoolexecutor.callerrunspolicy: This task is handled by the calling thread three. java comes with four thread pools
Newsinglethreadexecutor: Creates a fixed-size thread pool. Each time a task is committed, a thread is created until the thread reaches the maximum size of the threads pool. Once the maximum size of the thread pool is reached, the thread pool will be replenished with a new thread if it ends up executing an exception.
Newfixedthreadpool: Creates a fixed-size thread pool. Each time a task is committed, a thread is created until the thread reaches the maximum size of the threads pool. Once the maximum size of the thread pool is reached, the thread pool will be replenished with a new thread if it ends up executing an exception.
Newcachedthreadpool: Creates a cacheable thread pool. If the size of the thread pool exceeds the thread required to process the task, then a partially idle (60 second non-performing task) thread is reclaimed, and when the number of tasks increases, the thread pool can intelligently add new threads to handle the task. This thread pool does not limit the size of the thread pool, and the thread pool size is entirely dependent on the maximum thread size that the operating system (or JVM) can create.
Newscheduledthreadpool: Create a thread pool of unlimited size. This thread pool supports timing and the need to perform tasks periodically four. Component of the thread pool 1. Threads Pools Manager: Creates, destroys, and manages thread pooling, placing worker threads in the thread pool 2. Worker thread: A thread that can loop through a task and wait 3 when there is no task. Task queue: Provides a buffering mechanism Place tasks that are not processed in the Task Queue 4. Task interface: Is the interface that each task must implement, it is mainly used to specify the entry of the task, the finishing work after the completion of the task, the execution state of the task, and so on, the worker thread dispatches the task execution five through the interface. The number of core threads in Poolsize thread pool, When a task is submitted, the thread pool creates a new thread to perform the task until the current number of threads equals corepoolsize, and if the current number of threads is corepoolsize, the continuation of the committed task is saved to the blocking queue, waiting to be executed, if the blocking queue is full, Then create a new thread to perform the current task, until the thread pool has reached maxpoolsize, then there are tasks that can only execute reject () to handle the task; six. Thread pool status (5) 1, running:-1 << count_bits, That is, the high 3 bits are 111, the thread pool of that State receives new tasks and handles the tasks in the blocking queue, 2, shutdown:0 << count_bits, which is 3 bits 000 high, the thread pool of that state will not receive new tasks, but will handle the tasks in the blocking queue; 3, STOP: 1 << count_bits, that is, 3 bits High is 001, the thread of this state does not receive new tasks, does not handle the tasks in the blocking queue, and interrupts the running tasks, 4, Tidying:2 << count_bits, which is 3 bits high 010, This state indicates that the thread pool is optimized for threading, 5, Terminated:3 << count_bits, which is 3 bits 011, which indicates that the thread pool stopped working; seven. Submit a task to the thread pool
execute () internal implementation1. First to know the number of threads in the current thread pool through Workcountof () and, if less than corepoolsize, to create a thread from Addworker () and perform the task; otherwise, put the task into a blocking queue; 2. If the task can be successfully placed in a blocking queue, if the current thread pool is a non-running state, the task is removed from the blocking queue and then executed reject () to handle the task, and if the pool of current threads is in running state, you need to check the thread pool again (because it is possible after the last check Thread resources are freed), if there are idle threads, if any, perform the task, 3, if the task cannot be placed in the blocking queue, the blocking queue is full, then a new thread will be created through Addwoker () to perform this task, and if Addwoker () execution fails, Description thread pool threads reach Maxpoolsize, then execute reject () processing task;
Sumbit () internal implementationThe callable task that will be submitted is encapsulated as a Futuretask object Futuretask class implements the Runnable interface so that it can be executed through Executor.execute () commit futuretask to the thread pool, The final execution is the Futuretask run method; Compare: Two methods can submit a task to the thread pool, the return type of the Execute () method is void, it is defined in the executor interface, and the Submit () method can return the future object holding the calculation result , which is defined in the Executorservice interface, it expands the executor interface, and other thread pool classes like Threadpoolexecutor and Scheduledthreadpoolexecutor have these methods.
Summary executor () vs Submit ():(1) The Execute () method is actually the method declared in the executor, the implementation of the Threadpoolexecutor, this method is the core method of Threadpoolexecutor, this method can be submitted to the thread Pool A task, To the thread pool to execute. (2) The Submit () method is a method declared in Executorservice, which has been implemented in Abstractexecutorservice and has not been rewritten in threadpoolexecutor. This method is also used to submit a task to the thread pool, but unlike the Execute () method, it can return the result of the task execution and see the implementation of the Submit () method, and it will actually be called the Execute () method. It only uses the future to get the results of the task execution. Eight. The thread pool shutdown Threadpoolexecutor provides two methods for closing the thread pool, respectively, shutdown () and Shutdownnow (), Where:
shutdown(): Does not terminate the thread pool immediately, but waits until all tasks in the task cache queue have been executed before terminating, but no longer accepting new tasks
Shutdownnow(): Terminates the thread pool immediately, attempts to break the task in progress, and empties the task cache queue, returning tasks that have not yet been performed nine. implementation
Import Org.junit.test;import Java.util.concurrent.executorservice;import Java.util.concurrent.executors;import Java.util.concurrent.scheduledthreadpoolexecutor;import Java.util.concurrent.timeunit;public class TestExecutor {@ Test public void Testsinglethreadexecutorpool () {Executorservice pool = executors.newsinglethreadexecutor (); Thread T1 = new MyThread (); Thread t2 = new MyThread (); Thread t3 = new MyThread (); Thread T4 = new MyThread (); Thread T5 = new MyThread (); Pool.execute (t1); Pool.execute (T2); Pool.execute (T3); Pool.execute (T4); Pool.execute (T5); Pool.shutdown (); /* Pool-1-thread-1 is executing ... pool-1-thread-1 is executing ... pool-1-thread-1 is executing ... pool-1-thread-1 is practising Line ... pool-1-thread-1 is executing ... */} @Test public void Testfixthreadexecutorpool () {//Create a reusable Thread pool with fixed number of threads executorservice pool = Executors.newfixedthreadpool (2); The Runnable interface object is created, and the thread object of course implements the Runnable interface thread T1 = new MyThread (); Thread t2 = new MyThread (); Thread t3 = new MyThread (); Thread T4 = new MyThread (); Thread T5 = new MyThread (); Put the thread into the pool for execution pool.execute (T1); Pool.execute (T2); Pool.execute (T3); Pool.execute (T4); Pool.execute (T5); Close the thread pool Pool.shutdown (); /* *pool-1-thread-1 is executing ... *pool-1-thread-2 is executing ... *pool-1-thread-1 is performing ... *pool-1-thread- 2 executing ... *pool-1-thread-1 is executing ... */} @Test public void Testcachedthreadexecutorpool () {/ /Create a thread pool with a reusable number of fixed threads executorservice pool = Executors.newcachedthreadpool (); The Runnable interface object is created, and the thread object of course implements the Runnable interface thread T1 = new MyThread (); Thread t2 = new MyThread (); Thread t3 = new MyThread (); Thread T4 = new MyThread (); Thread T5 = new MyThread (); Putting a thread into the pool for execution. Execute (T1); Pool.execute (T2); Pool.execute (T3); Pool.execute (T4); Pool.execute (T5); Close the thread pool Pool.shutdown (); /* Pool-1-thread-1 is executing ... pool-1-thread-2 is executing ... pool-1-thread-1 is executing ... pool-1-thread-3 is practising Line ... pool-1-thread-1 is executing ... */} @Test public void Testscheduledthreadpoolexecutor () {Sch Eduledthreadpoolexecutor exec = new Scheduledthreadpoolexecutor (1); Exec.scheduleatfixedrate (New Runnable () {//Every once in a while the exception public void run () {System.out.println ("= ==============="); }}, +, timeunit.milliseconds); Exec.scheduleatfixedrate (New Runnable () {//Print the system time every once in a while to prove that both are non-affected public void run () {System.ou T.println (System.nanotime ()); }}, +, timeunit.milliseconds); }/** ================ 440697961331385 440699965178923 440701962726589 ================ 440703964380898 440705963957505 ================ 440707961439581 440709966042376 440711 964335904 ================ */}
Java thread pool