How Java Thread Pools Work




The background and purpose of the working principle of the Java thread pool
: 1. Assume that the time required for a server to complete a task is: T1 time to create a thread, T2 time to execute the task in the thread, and T3 time to destroy the thread.
If: T1 + T3 is much larger than T2, thread pools can be used to improve server performance.
2. If each task arrives, a thread is created, and the thread is destroyed after the operation is completed. When there are many task requests, the application will create a lot of threads at the same time,
and there will be a lot of threads to switch at runtime. This kind of The overhead on system resources is very large.
3. In addition to the overhead of creating and destroying threads, active threads also consume system resources. Creating too many threads in a JVM can cause the system to run out of memory or "overswitch" by over-
consuming memory.
4. The thread pool is the solution proposed to solve the above problems.
5. The ThreadPoolExecutor class in Java is a class that implements a thread pool.


There are four basic components of
the thread pool: 1. Thread pool manager (ThreadPool): used to create and manage thread pools, including creating thread pools, destroying thread pools, and adding new tasks;
2. Worker threads (PoolWorker): in the thread pool Threads are in a waiting state when there are no tasks, and can execute tasks cyclically. Worker threads are created and destroyed by the thread pool (without manual creation);
3. Task interface (Task): the interface that each task must implement for the purpose of The worker thread schedules the execution of tasks, which mainly specifies the entry of the task, the finishing work after the task is executed, the execution status of the task, etc.;
4. Task Queue (taskQueue): used to store unprocessed tasks. Provides a buffer mechanism. (The task is to write the instance object according to the business requirements (implement the implements Runnable interface run))


The working principle of the thread pool:
1. When the application starts, several worker threads are initialized and stored in the thread pool. In this way, the worker thread (Worker in ThreadPoolExecutor) is created.
2. When the task arrives, put the task in the task queue (workQueue in ThreadPoolExecutor). (eg: threadPoolExecutor.execute(myTask);)
3. The worker thread takes out the task from the task queue and runs the task interface to process the task.
4. When there are too many tasks in the task queue, the thread pool manager will create a new worker thread (Worker in ThreadPoolExecutor) and put it into the thread pool, and the new worker thread will also process the task.
5. In this way, the number of threads in the application is reduced, and threads are not created when running tasks; the number of threads is reduced, and the system overhead of thread switching is also reduced.
6. It is to turn the task into an instance (implements the Runnable interface run), and create a specified thread (Worker in ThreadPoolExecutor) to continuously
take out the task instance from the task queue (workQueue in ThreadPoolExecutor), and run the run method in the instance.



ThreadPoolExecutor class in Java
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);
    ...
}


1.corePoolSize: the size of the core pool, (the number of main worker threads)
2.maximumPoolSize: the maximum number of threads in the thread pool (those larger than corePoolSize are temporary, only created and placed in the thread pool when needed)
3.keepAliveTime : Indicates how long the thread will be terminated when there are no tasks to execute.
4.unit: the time unit of the parameter keepAliveTime,
TimeUnit.DAYS; //days
TimeUnit.HOURS; //hours
TimeUnit.MINUTES; //minutes
TimeUnit.SECONDS; //seconds
TimeUnit.MILLISECONDS; //milliseconds
TimeUnit.MICROSECONDS; // subtle
TimeUnit.NANOSECONDS; //nanoseconds

5.workQueue: a blocking queue used to store tasks waiting to be executed.
6.threadFactory: a thread factory, mainly used to create threads;
7.handler: a strategy for refusing to process tasks, with the following four values:
ThreadPoolExecutor.AbortPolicy: Aborts the task and throws a RejectedExecutionException.
ThreadPoolExecutor.DiscardPolicy: also discards tasks, but does not throw exceptions.
ThreadPoolExecutor.DiscardOldestPolicy: Discard the task at the front of the queue and retry the task (repeat this process)
ThreadPoolExecutor.CallerRunsPolicy: The task is handled by the calling thread




Some other important member variables in the ThreadPoolExecutor class
private final BlockingQueue<Runnable> workQueue; //Task cache queue, used to store tasks waiting to be executed
private final ReentrantLock mainLock = new ReentrantLock(); //The main state lock of the thread pool, for the thread pool state (such as the thread pool size
                                                              //, runState, etc.) changes must use this lock
private final HashSet<Worker> workers = new HashSet<Worker>(); //Used to store the working set

private volatile long keepAliveTime; //Thread inventory time
private volatile boolean allowCoreThreadTimeOut; //Whether it is allowed to set the survival time for the core thread
private volatile int corePoolSize; //The size of the core pool (that is, when the number of threads in the thread pool is greater than this parameter, the submitted task will be put into the task cache queue)
private volatile int maximumPoolSize; //The maximum number of threads the thread pool can tolerate

private volatile int poolSize; //The current number of threads in the thread pool

private volatile RejectedExecutionHandler handler; //Task rejection policy

private volatile ThreadFactory threadFactory; //Thread factory, used to create threads

private int largestPoolSize; //Used to record the largest number of threads that have ever appeared in the thread pool

private long completedTaskCount; //Used to record the number of tasks that have been executed




submission of tasks
execute() //This method can submit a task to the thread pool for execution by the thread pool.
submit() //This method is also used to submit tasks to the thread pool, but it is different from the execute() method in that it can return the result of task execution
shutdown() //The thread pool is in the SHUTDOWN state. At this time, the thread pool cannot accept new tasks. It will wait for all tasks to be executed.
shutdownNow() //The thread pool is in STOP state. At this time, the thread pool cannot accept new tasks and will try to terminate the executing tasks



example:
package ThreadPool;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {
	public static void main(String[] args) {
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 200, TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue(100));

		for (int j = 0; j < 16; j++) {
			for (int i = 0; i < 16; i++) {
				MyTask myTask = new MyTask(j*100+i);
				threadPoolExecutor.execute(myTask);
				System.out.println("Number of threads in the thread pool: " + threadPoolExecutor.getPoolSize() + ", the number of tasks waiting to be executed in the queue: " + threadPoolExecutor.getQueue().size()
						+ ", the number of completed tasks: " + threadPoolExecutor.getCompletedTaskCount());
			}
		}
		threadPoolExecutor.shutdown();
	}
}


package ThreadPool;

class MyTask implements Runnable { //Implement interface Runnable interface run,
	private int taskNum;

	public MyTask(int num) {
		this.taskNum = num;
	}

	public void run() {//Interface run, your task logic is implemented here
		System.out.println("Executing task " + this.taskNum);
		System.out.println("task " + taskNum + "execution completed");
	}
}



Spring thread pool (TaskExecutor)
reference text: http://lishaorui.iteye.com/blog/1051823


Reference text: http://www.cnblogs.com/dolphin0520/p/3932921.html
Reference text: http://www .blogjava.net/stevenjohn/archive/2011/12/12/366161.html
Reference text: http://wenku.baidu.com/link?url=GoqD2-ouxAVhPVfs20rqelSjDPs8IPHq6dQanWuJpca8Em9yxiGMLoHS2-1Pyq8tec9Z25z8FiqDJBhWhKUSAd82YEW4Bu7wio7

Guess you like

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