随着并发的增多,创建、销毁线程的动作也随之增多,所以资源的浪费也随之增多,并且线程的数量变大,管理的难度也会随之加大------于是线程池小伙伴就出来前言
看到这些好处有点心动,但是我们不仅要知其然还要知其所以然
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
milliseconds,
runnableTaskQueue,
threadFactory,
handler);
我们可以使用executor向线程池提交任务,但是此种方式没有返回值,无法判断任务是否已经执行成功,参数为runable对象实例;
此方法不为ThreadPoolExecutor类自有的方法,他是属于ThreadPoolExecutor父类方法,返回future通过get判断任务是否执行成功,get会阻塞直到任务完成,源码如下
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
不难发现提交任务是传入了ftask对象,看看newTaskFor()
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
返回的一个FutureTask实例
查看对应的get方法,返回一个int类型的值
shutdown是将线程池的状态设置为shutdown状态,但是并不会停止正在工作的线程,shutdownNow将线程池的状态设置为stop状态,并且尝试停止正在执行任务的线程
当线程池当中有新提交的任务时,判断流程如下:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//判断是否小于基本线程池
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//如果线程池正在运行并且添加到工作队列
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
//如果添加时的瞬间有人调用了shutdown方法的应急措施
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
一家工厂,有一个厂房,厂房里有5个工人(基本线程),每个工人负责处理一个机器(任务),这个厂房最多能容纳10个人(最大线程数),这个工厂还有一个仓库,仓库可以存储5个机器,当工人处理一个机器之后,会从仓库拿一个机器继续干活,当需求比较大的时候,老板发现仓库安置不下了,于是将机器直接放到厂房了,同时新招了几个人(总共不超过10个人),在厂房干活,当最后同时有超过15台机器的时候,没地方,也没人了,老板直接不接这个新的单子了(某种饱和策略)。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。