本人最近对java线程池又复习了一下,现在记录一下我的日志,方便以后查看,如果大家有更好的见解,欢迎评论留言。
我把线程池总结为以下六点和一些常用的方法。(名称都是我自己想的,非官方语言)
ThreadPoolExecutor
固定线程池
SingleThreadExecutor 单例线程池
CachedThreadPool 缓存线程池
ScheduledThreadPool 定时线程池
自定义线程池
一、ThreadPoolExecutor 我理解是线程池的基类,其他的线程池都是在这个的基础上改装的
源码:public ThreadPoolExecutor(
int corePoolSize,//线程池中核心线程的数量
int maximumPoolSize,//线程池中最大线程数量
long keepAliveTime,//非核心线程的超时时长,当系统中非核心线程闲置时间超过keepAliveTime之后,则会被回收。如果ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,则该参数也表示核心线程的超时时长
TimeUnit unit,//第三个参数的单位,有纳秒、微秒、毫秒、秒、分、时、天等
BlockingQueue<Runnable> workQueue,//线程池中的任务队列,该队列主要用来存储已经被提交但是尚未执行的任务。存储在这里的任务是由ThreadPoolExecutor的execute方法提交来的。
ThreadFactory threadFactory,//为线程池提供创建新线程的功能,这个我们一般使用默认即可
RejectedExecutionHandler handler//拒绝策略,当线程无法执行新任务时(一般是由于线程池中的线程数量已经达到最大数或者线程池关闭导致的),默认情况下,当线程池无法处理新线程时,会抛出一个RejectedExecutionException。
)
创建线程池:
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
3, //线程池中核心线程的数量
5, //线程池中最大线程数量
//非核心线程的超时时长,当系统中非核心线程闲置时间超过keepAliveTime之后,则会被回收。如果ThreadPoolExecutor
//的allowCoreThreadTimeOut属性设置为true,则该参数也表示核心线程的超时时长
10,
TimeUnit.SECONDS,//第三个参数的单位,有纳秒、微秒、毫秒、秒、分、时、天等
//线程池中的任务队列,该队列主要用来存储已经被提交但是尚未执行的任务。
//存储在这里的任务是由ThreadPoolExecutor的execute方法提交来的。
new LinkedBlockingDeque(128));
启动线程:poolExecutor.execute(runable);
二、 固定线程池
源码:public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
创建线程池:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(
3//核心线程数
);
启动线程:
threadPoolExecutor.execute(runable);
三、SingleThreadExecutor 单例线程池
源码:public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
创建线程池:
ExecutorService singleThreadExecutor= Executors.newSingleThreadExecutor();
启动线程:
singleThreadExecutor.execute(runnable);
四、CachedThreadPool 缓存线程池
源码:public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
创建线程池:
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
启动线程:
cachedThreadPool.execute(runnable);
五、ScheduledThreadPool 定时线程池
源码:public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
创建线程池:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
启动线程:2种
1、延迟启动任务
源码:
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
启动:scheduledExecutorService.schedule(runnable, 1, TimeUnit.SECONDS);
2、 延迟定时执行任务
源码:
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
启动:
scheduledExecutorService.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS);
3、延迟执行任务
源码:
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
启动线程:
scheduledExecutorService.scheduleWithFixedDelay(runnable, 1, 1, TimeUnit.SECONDS);
六、自定义线程池
继承 ThreadPoolExecutor
栗子:
class MyThreadPool extends ThreadPoolExecutor{
public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
Log.d("google_lenve_fb", "beforeExecute: 开始执行任务!");
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Log.d("google_lenve_fb", "beforeExecute: 任务执行结束!");
}
@Override
protected void terminated() {
super.terminated();
//当调用shutDown()或者shutDownNow()时会触发该方法
Log.d("google_lenve_fb", "terminated: 线程池关闭!");
}
}
七、线程池常用方法:
1.shutDown() 关闭线程池,不影响已经提交的任务2.shutDownNow() 关闭线程池,并尝试去终止正在执行的线程
3.allowCoreThreadTimeOut(boolean value) 允许核心线程闲置超时时被回收
4.submit 一般情况下我们使用execute来提交任务,但是有时候可能也会用到submit,使用submit的好处是submit有返回值