意义:为了避免系统频繁创建和销毁线程,提前创建线程,放入线程池,使用时直接获取,使用完返回线程池。在使用线程池后创建线程变成了从线层池获得空闲线程,关闭线程变成了归还线程。
创建线程池常用方式
FixedTreadPool 固定大小线程池 核心线程数和最大线程数一样,空闲线程存活0毫秒,构建任务队列采用LinkedBlockingQueue,他的容量为Integer的最大值,可能会OOM,不建议使用
SingleThreadExecutor 单个线程线程池:核心线程数和最大线程数一样都是1,空闲线程存活0毫秒(意味着空闲线程不会被销毁),建任务队列采用LinkedBlockingQueue,他的容量为Integer的最大值,可能会OOM,不建议使用
CachedThreadPool 可缓存线程池:核心线程数为0,说明线程池里全是非核心线程,存活时间60s,使用同步队列,容量为Integer的最大值,同理
ScheduledThreadPoolExecutor:调度线程池,具备执行定时或延时任务的线程池,执行周期性任务
ThreadPoolExecutor: 原生线程池,自定义线程池参数
常用方法:
execute与submit
execute方法在Executor接口中,用于像线程池提交Runnable任务,无返回值、
submit位于ExecutorService中,也可以提交Runnable任务,作用是观察任务是否执行完毕,取消任务等或者使用多参数对执行结果打印。Callable任务执行结果会封装到Future对象中,进行返回
取消任务cancel
表示尝试中断正在执行的任务,也就调用interrupt方法,取消成功返回ture
1.取消未执行任务,就是任务队列的线程
2.取消正在执行的任务,需要将参数设置为true
关闭线程池shutdown与shutdownNow
shutdown:不会立即关闭,不在接受新任务继续执行任务队列未执行的任务,
shutdownNow:关闭线程池,不在接受新任务,尝试停止正在执行的任务,List形式返回未执行的任务。在需要立即停止时使用。
线程池工作原理
开始-获取ctl(runState运行的状态以及workerCount(线程池里活跃的线程数))
当workerCount小于corePoolSize时- addWorker(command,true)- 返回结果是否成功-若不成功重新获取ctl
runState=RUNING并且将command(存的Runable任务)添加到workQueue是否成功-失败(队列满)- addWork(command,false)- 拒绝策略-结束
成功-重新获取ctl值-runState是否等于RUNNING(接受新任务)- !刚刚添加到workQueue中的comman移除-执行拒绝策略
等于RUNNING-workerCount是否为0-addWorker(null,false)
addworker:开始-获取ctl值在获取runState判断是否为RUNNING状态·和SHUTDOWN状态并且入参为空工作队列不为空-否则失败-在获取线程池中活跃的线程数WorkerCount-判断是否大于CAPACTY(29个1)-若不大于-判断
入参core是否为true(大于等于核心线程池数)-线程池+1-在获取ctl判断与最初的runState是否一样,不一样在重新执行此过程
总结:当我们提交任务,线程池会根据corePoolSize大小创建若干任务数量线程执行任务 2. 当任务的数量超过corePoolSize数量,后续的任务将会进入阻塞队列阻塞排队 3. 当阻塞队列也满了之后,那么将会继续创建(maximumPoolSize-corePoolSize)个数量的线程来 执行任务,如果任务处理完成,maximumPoolSize-corePoolSize额外创建的线程等待 keepAliveTime之后被自动销毁 4. 如果达到maximumPoolSize,阻塞队列还是满的状态,那么将根据不同的拒绝策略对应处理