线程池的那些事情-未必足够详细,但求能看得明白
说到线程池,我以前总是使用别人的写好的工具类或者直接百度去查找,有时候被问到了问题总是答不好,知其然不知其所以然,这里简单讲解一下个人见解:
1.首先我们需要知道线程池是个啥?
2.线程池解决了什么问题?
3.线程池怎么使用?
从第一个点开始了解,线程池是什么?
这段话是我复制过来的,因为我写不出这么好的见解。
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。
第二问线程池解决了什么问题?
(1)提升性能:线程池能独立负责线程的创建、维护和分配。在执行大量异步任务时,可以不需要自己创建线程,而是将任务交给线程池去调度。线程池能尽可能使用空闲的线程去执行异步任务,最大限度地对已经创建的线程进行复用,使得性能提升明显。
(2)线程管理:每个Java线程池会保持一些基本的线程统计信息,例如完成的任务数量、空闲时间等,以便对线程进行有效管理,使得能对所接收到的异步任务进行高效调度。
第三步就需要通过代码来说明了,希望对你有所帮助:
ThreadPoolExecutor:java通过这个类创建线程池。
这个类提供了以下参数设置:
corePoolSize:核心线程数量
maximumPoolSize:最大线程数量
keepAliveTime: 空闲线程的存活时间
unit:时间单位
workQueue:工作队列(也就是线程工作模式-阻塞策略)
那我们如何创建一个基本得线程池,这个类中提供了几种常用的function
1.newSingleThreadExecutor
创建Single线程的线程池,只有1个核心线程,没有非核心线程,
2.newFixedThreadPool
创建fixed线程的线程池,参数是核心线程数,最大线程是Interger的最大值,非核心线程空闲即关闭
3.newCachedThreadPool
创建Cache线程池,没有核心线程,所有的线程都是非核心,任务等待时间60秒
4.newScheduledThreadPool
创建scheduled线程池,参数为核心线程,非核心线程数为Integer的最大值,空闲关闭时间为10毫秒
如何创建自定义参数的线程池呢,当然是通过ThreadPoolExecutor类:
public ThreadPoolExecutorgetThreadPool() {
if (threadPoolExecutor ==null) {
synchronized (MyThreadPool.class) {
if (threadPoolExecutor ==null) {
threadPoolExecutor =new ThreadPoolExecutor(2,
10,
60L,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(10 -2));
threadPoolExecutor.allowCoreThreadTimeOut(true);
}
}
}
return threadPoolExecutor;
}
如何使用?
常见任务
public void addTask(Runnable runnable) {
getThreadPool().execute(runnable);
}
延时任务
public void addDelayTask(Runnable runnable, long delay, @NonNull String tag) {
ScheduledFuture schedule = getScheduledThreadPool().schedule(runnable, delay, TimeUnit.SECONDS);
scheduledFuturesMap.put(tag, schedule);
}
如何取消任务?
常见任务
public void removeTask(Runnable runnable) {
getThreadPool().remove(runnable);
}
延时任务
public boolean removeDelayTask(String tag) {
ScheduledFuture scheduledFuture =scheduledFuturesMap.get(tag);
if (scheduledFuture ==null)return true;
if (!scheduledFuture.isCancelled() && !scheduledFuture.isDone()) {
Log.e("MainActivity", "removeDelayTask 111");
return scheduledFuture.cancel(true);
}
scheduledFuturesMap.remove(tag);
return true;
}
如果上面的代码看不明白请移步到我写的demo中,后续肯定也会更加完善。
死亡面试题之常见三问
1.线程池是如何工作的?
2.线程给定参数后是如何工作的?
3.为何阿里巴巴团队不让使用Executors中的四种默认创建模式,为什么?
上面这些后面肯定会补上的,时间问题哈哈哈哈
网友评论