public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
线程池是如何重复利用空闲的线程来执行任务的?_Java知音_的博客-CSDN博客
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory)); }
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory); }
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory); }
这里有线程复用
ThreadPoolExecutor 类里面 方法
内部类Work类里面实现了run方法 run方法又调用了ThreadPoolExecutor的runWorker(ThreadPoolExecutor.Worker var1) 把自己work对象传进去了(实现了runnable)里面循环取任务执行
runWorker(ThreadPoolExecutor.Worker var1)
不停地while循环获取task任务 执行 Work类里面的run方法 work实现了
Runnable接口
getTask是从队列里面获取任务runnable
excute方法 就是加入
addWorker 或者拒绝reject
而线程池里面的核心线程是一直会存在的,如果没有任务则会阻塞,所以线程池里面的用户线程一直会存在.而shutdown方法的作用就是让这些核心线程终止,下面在简单看下shutdown重要代码:
使用线程池时候当程序结束时候记得调用shutdown关闭线程池_加多的博客-CSDN博客_线程池shutdown之后线程还存在
2,如果当前活动线程数小于等于核心线程数(或者不允许核心线程超时),同样也是去缓存队列中取任务,但当缓存队列中没任务了,就会进入阻塞状态(队列的take方法),直到能取出任务为止(也就是队列中被新添加了任务时),因此这个线程是处于阻塞状态的,并不会因为缓存队列中没有任务了而被销毁。这样就保证了线程池有N个线程是活的,可以随时处理任务,从而达到重复利用的目的。
综上所述,线程之所以能达到复用,就是在当前线程执行的runWorker方法中有个while循环,while循环的第一个判断条件是执行当前线程关联的Worker对象中的任务,执行一轮后进入while循环的第二个判断条件getTask(),从任务队列中取任务,取这个任务的过程要么是一直阻塞的,要么是阻塞一定时间直到超时才结束的,超时到了的时候这个线程也就走到了生命的尽头。