面试题:讲一下线程池(腾讯、京东面试题)
一、为什么使用线程池
由于创建和销毁线程都需要很大的开销,运用线程池就可以大大的缓解这些内存开销很大的问题;可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存。
二、线程池的处理流程
创建线程池需要使用 ThreadPoolExecutor 类,它的构造函数参数如下:
public ThreadPoolExecutor(
int corePoolSize, //核心线程的数量
int maximumPoolSize, //最大线程数量(核心线程+核心意以外的线程)
long keepAliveTime, //超出核心线程数量以外的线程空闲时的存活时间
TimeUnit unit, //存活时间的单位
BlockingQueue<Runnable> workQueue, //存放来不及处理的任务的队列,是一个BlockingQueue。
ThreadFactory threadFactory, //生产线程的工厂类,可以定义线程名,优先级等。
RejectedExecutionHandler handler // 当任务无法执行时的处理器
) {...}
线程池执行的具体方法:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//1.当前池中线程比核心数少,新建一个线程执行任务
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//2.核心池已满,但任务队列未满,添加到队列中
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command)) //如果这时被关闭了,拒绝任务
reject(command);
else if (workerCountOf(recheck) ==