为避免线程消耗过多资源影响性能,(创建与启动线程,线程销毁,线程调度的开销,线程数量受限于CPU处理器数量),使用线程池来管理线程
线程池:避免一任务创建一线程带来的开销和性能问题,预先创建好可供使用可复用的线程,客户端将任务以对象传递给线程池,线程池将任务缓存到等待队列中,线程池不断抽取一个可使用的线程从队列取出执行任务。
Executors工具类 隐式实现了Executor的execute()向线程池提交任务
封装好的常用方法:(底层通过ThreadPoolExecutor实现ExecutorService)
newCachedThreadPool()
//核心线程数=0 每次提交新任务都会创建新的非核心线程执行,60秒回收空闲线程,因为动态创建销毁,比其他更适合大量耗时短,且提交频繁的任务
newFixedThreadPool(int nThreads)// 核心线程数=n
newSingleThreadExecutor// 核心线程数=1
常用方法:
execute(Runnable )
Future submit(Runnable / collable<T>) 额外支持Callable
shutdown()
newScheduledThreadPool(int corePoolSize)// 核心线程数=n(支持调度的线程)
它通过ScheduledThreadPoolExecutor实现调度,通过ThreadPoolExecutor创建线程池
常用方法:
schedule(Runnable,3,TimeUnit.SECONDS) //延迟三秒执行
scheduleAtFixedRate(Runnable, 3, 2, TimeUnit.SECONDS)
//延迟3秒开始,每隔2秒重新执行,但具体时间run决定
scheduleWithFixedDelay(Runnable, 3, 2, TimeUnit.SECONDS)
//和上一样,但具体时间run+2决定
线程池底层大多都是使用ThreadPoolExecutor构造方法来创建
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler) { xx}
corePoolSize 是指定的核心线程数量,但当任务量超过该数量时,会创建额外的非核心线程。线程总数量是 maximumPoolSize,满了后若此时新增任务而等待队列已满,会执行拒绝策略。
keepAliveTime决定非核心线程空闲时间,unit单位,超时才回收,不超时立即回收(白创建)
BlockingQueue等待队列方案:
直接提交队列:SynchronousQueue 无容量,直接提交执行; 若无空闲线程,则创建线程
有界任务队列:ArrayBlockingQueue(int)指定容量
无界任务队列:LinkedBlockingQueue(默认方案,无限容量,避免拒绝,但可能内存耗尽)
优先任务队列:PriorityBlockingQueue
ThreadFactory线程工厂接口:
默认工厂核心是使用ThreadFactory的Thread newThread(Runnable r任务);来实现创建
在创建线程池过程中也可以自定义实现newThread方法
如果不需要线程在程序结束后仍然要继续运行,一般都要setDaemon(true)守护线程和主线程一起回收
RejectedExecutionHandler 拒绝策略接口:
是ThreadPoolExecutor中的静态内部类可直接调用:
AbortPolicy:抛出RejectedExecutionException异常。(默认策略)。
DiscardPolicy:选择无视
CallerRunsPolicy:直接用外部提交任务的线程来执行,不创建妨碍线程池中的线程,保证新任务不会被丢弃,但会增加任务执行的上下文切换,容易降低程序的性能
DiscardOldestPolicy: 丢弃将执行的任务,尝试添加新任务。以避免新任务等待太长时间或丢失。
手动用ThreadPoolExecutor 实现 RejectedExecutionHandler 及其方法可以自定义策略
监控线程池:
待补