Analysis of Java Intermediate Thread Pool Source Code

  This article is from http://blog.csdn.net/liuxian13183/  , and the reference must be indicated!


The thread pool is generated along with the generation of threads, and is mainly used for thread reuse to reduce memory leaks.

The thread pool uses Thread as the executor and the Runnable interface as the executor, and each executor completes the execution in the form of tasks.


The task below refers to a Worker object that implements the Runnable interface, and the task is executed in Thread

principle:

corePoolSize: the number of active threads, hereinafter referred to as core (cannot be less than 0)

maxPoolSize: The total number of thread pools, hereinafter referred to as max (cannot be less than 0, core must be less than max)

keepAliveTime: more than the idle time of core threads, the timeout is stopped, hereinafter referred to as keep (cannot be less than 0)

ctl: In conjunction with the isRunning method, it is used to mark the number of threads and the running status. If not, the thread pool will be closed.

A new task is added. If the number of threads is less than core, a new thread is created until the number is equal to core;

 

ExecutorService:

newCachedThreadPool unbounded thread pool, dynamic transformation, default executor, hereinafter referred to as Cached

newFixedThreadPool fixed size executor, hereinafter referred to as Fixed, default ExecutorService

newSingleThreadExecutor single-threaded executor, hereinafter referred to as Single

Queue:

SynchronousQueue does not need to wait, directly enters the thread execution, requires the use of Cached, otherwise the task will be abandoned if there is no thread for a while

LinkedBlockingQueue is an unbounded queue, which is used for waiting when the core is busy. The tasks have no influence on each other. The advantage is that a large number of tasks can be accepted in a short time.

ArrayBlockingQueue is a bounded queue, using large pools and small queues to reduce resource consumption (CPU, IO, thread switching)

Policy:

RejectedExecutionHandler throws a rejected exception when the ExecutorService shuts down

CallerRunsPolicy:减缓任务的执行速率

DiscardPolicy: 直接抛弃

DiscardOldestPolicy:位于栈顶的任务被抛弃,会重新执行此任务,则抛弃老的任务

 

Worker:

使用AbstractQueuedSynchronizer锁

第一、保证操作去唤醒一个等待的任务,而不是中断一个正在执行的任务

第二、作为一个互斥锁,不使用ReentrantLock,希望在调用setCorePoolSize方法后,不必使worker重新获得锁

 

execute方法:

任务将会在一个线程中被处理,线程可能是一个新线程(线程数小于corePoolSize),也可能是一个已经存在的线程(线程数大于corePoolSize,小于maxPoolSize)

4种情况会被拒绝执行:

第一、线程池已经shudown(主动执行shutdown,或被interrupt)

第二、线程数已经超过maxPoolSize(可设为Integer.MaX_VALUE以防止发生)

第三、线程池为空

第四、超时

拒绝执行,如果使用的handler为RejectedExecutorHandler(默认),则任务被抛弃,并报错

线程没有RuntimePermission,则会被停止

执行前后,分别会运行beforeExecute和afterExecute

执行:

小于core则new新thread

大于core则优先进入queue等待

如不能则new新thread

大于max则任务默认被拒绝

 

shutdown方法:

顺序关闭所有任务(任务池的线程仍会执行完毕,但新任务不再被接受)

executor长久不被调用,同时无剩余线程,会自动执行shutdown;

实现方式:

目的让空闲线程被杀掉

方式有二,设置keep时间短一点,其次设置core小一点同是allowCoreThreadTimeOut为true

 

shutdownNow方法:

立即停止所有任务,包含正在执行的,并返回这些“正在执行的任务”的list集合

 

remove方法:

停止未执行的任务;如果使用submit把任务当成future类型,则不会停止 

 

purge方法:

清除已经被停止的future任务,用于存储功能改造;如果被其他线程干扰,则会失败。

 

判断启动corePool的数量:

prestartCoreThread:启动一条core线程

ensurePrestart:同上,如果corePoolSize为0也启动一条线程

prestartAllCoreThreads:将所有core线程均启动

 

Tips:

1、

如果任务数大于core但小于max,则新线程被创建(建议max为Integer.MAX_VALUE)

提示:core和max应该被动态的设置,keep用于有效减少资源占用

将allowCoreThreadTimeOut设为true,可以让core同样有此功效(时间需要大于0,超时后一个个被interrupt),设置后直接把运行的空闲任务全部清除

2、

为获得更大效率,一般IO读写设置core为2*CpuSize,逻辑较多避免上下文切换,设置为CpuSize

3、

submit比 exexute仅多一个返回值,标识完成。

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325959869&siteId=291194637
Recommended