这篇文章主要讲解了“线程池ThreadPoolExecutor有什么作用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“线程池ThreadPoolExecutor有什么作用”吧!
一、初始化线程池(4种):
1、newFixedThreadPool()
public final static ExecutorService esPool = Execustor.newFixedThreadPool(50);
特点:corePoolSize == maxPoolSize,使用LinkedBlockingQueue作为堵塞队列;没有可执行任务时不会释放线程池;
2、newCachedThreadPool()
public final static ExecutorService esPool = Execustor.newCachedThreadPool();
特点:默认缓存60s,线程数可以达到Integer.MAX_VALUE,内部使用SynchronousQueue作为堵塞队列;没有可执行任务时,达到keepAliveTime会释放线程资源,新任务没有执行空闲线程就得重新创建新的线程,会导致系统开销;使用时,注意控制并发数,减少创建新线程数;
3、newScheduleThreadPool()
public final static ExecutorService esPool = Execustor.newScheduleThreadPool(50);
特点:指定时间内周期性内执行所提交的任务,一般用于定时同步数据;
4、newSingleThreadExecutor()
特点:初始化只有一个线程的线程池;内部使用LinkedBlockingQueue作为堵塞队列;
二、源码实现:
1、ThreadPoolExecutor构造器
public ThreadPoolExecutor(
int corePoolSize,//核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//线程存活时间(必须在线程数在corePoolSize与maximumPoolSie之间时,存活时间才能生效)
TimeUnit unit,//存活时间的单位
BlockingQueue<Runnable> workQueue,//堵塞队列
RejectedExecutionHandler handler//当拒绝处理任务时的策略
) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
说明:堵塞队列BlockingQueue:1)ArrayBlockingQueue(数组结构的界限堵塞队列,FIFO);2)LinkedBlockQueue(链表结构的堵塞队列,FIFO);3)SynchronousQueue(不存储元素的堵塞队列,每次插入必须等到另一个线程移除);4)PriorityBlockingQueue(具有优先级的堵塞队列)。
拒绝处理任务的策略RejectedExecutionHandler :1)、ThreadPoolExecutor.AbortPolicy(抛弃当前线程,并抛出RejectedExecutionException异常)2)、ThreadPoolExecutor.DiscardPolicy(抛弃当前线程,不抛出异常);3)、ThreadPoolExecutor.DiscardOldestPolicy(抛弃最前面的任务,然后重新尝试此执行过程);4)、CallerRunnsPolicy(调用线程执行此任务)
2、execute()
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//获取当前线程的数量:workerCountOf()
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))//当当前线程数量小于corePoolSize时,就addWorker
return;
c = ctl.get();
}
//如果当前线程处于Running状态;
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
//检查线程池(因为可能在上次检查后,有线程资源被释放),是否有空闲的线程
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//如果当前线程处于非Running状态;
else if (!addWorker(command, false))
reject(command);
}
3、reject()
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}
4、submit()
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
//封装成一个FutureTask对象,FutureTask类实现Runnable接口
RunnableFuture<T> ftask = newTaskFor(task);
//执行execute(),通过execute提交到FutureTask线程池中等待被执行,最终执行FutureTask的run方法
execute(ftask);
return ftask;
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
5、线程状态
private static final int COUNT_BITS = Integer.SIZE - 3;
//即高3位为111,该状态的线程池会接收新任务,并处理阻塞队列中的任务;
private static final int RUNNING = -1 << COUNT_BITS;
//即高3位为000,该状态的线程池不会接收新任务,但会处理阻塞队列中的任务;
private static final int SHUTDOWN = 0 << COUNT_BITS;
//即高3位为001,该状态的线程不会接收新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务;
private static final int STOP = 1 << COUNT_BITS;
//即高3位为010,该状态表示线程池对线程进行整理优化;
private static final int TIDYING = 2 << COUNT_BITS;
//即高3位为011,该状态表示线程池停止工作;
private static final int TERMINATED = 3 << COUNT_BITS;
6、runWorker()(真正执行任务的接口)
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);//啥都没做
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
protected void afterExecute(Runnable r, Throwable t) { }
感谢各位的阅读,以上就是“线程池ThreadPoolExecutor有什么作用”的内容了,经过本文的学习后,相信大家对线程池ThreadPoolExecutor有什么作用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/anlen/blog/3070951