- 线程生命周期的开销(创建和关闭线程等开销)
- 活动线程消耗系统资源,大量空闲线程占用更多内存,给垃圾回收器带来压力。
- 过多的线程会影响稳定性,甚至拖垮程序。
过程:线程池管理一个工作者线程的同构池,并与工作队列绑定。它从工作队列中获取下一个任务并执行。
优点:
-
可以重用线程,减少创建和关闭线程的开销。
-
提高响应性,不需要创建线程也就不会延迟任务的执行。
-
通过调整线程池大小,可以保持处理器忙碌的同时防止过多线程竞争资源(耗尽内存)。
-
对于计算密集型任务,线程数为CPU+1。
-
包含I/O等阻塞操作可以加大线程池。
-
计算公式:No(threads) = No(CPU)*U(cpu)*(1+W/C)
No表示数量,U表述利用率,W/C为等待时间域计算时间的比率
- 线程池中一个任务依赖于其他任务的执行,就可能产生死锁。
- 解决:给同一线程池提交相互独立的任务,而不是彼此依赖的任务。
- 支持不同类型的任务执行策略
- 为任务提交和任务执行之间的解耦提供了标准方法
- 提供对生命周期的支持以及钩子函数
- 可以添加统计收集、应用程序管理机制和监视器等扩展
- 基于生产者-消费者模式
-
唯一方法
方法名 返回值 描述 execute(Runnable) void 在将来的某个时间执行给定的命令
-
继承Executor接口,添加了用于生命周期管理的方法
-
提供了三种生命周期状态:运行、关闭、终止
-
部分方法
方法名 返回值 描述 submit(Runnable) Future> 提交一个可运行的任务执行,并返回一个表示该任务的未来。 shutDown() void 平缓关闭:停止接受新任务,等待已提交任务完成 shutDownNow() List 强制关闭:尝试取消所有任务,返回等待的任务列表 isShutDown() boolean 判断是否关闭 isTerminated() boolean 所有任务完成会进入终止状态 awaitTermination(long, TimeUnit) boolean 等待进入终止状态,返回一段时间后是否关闭。通常后接shutdown -
实现类:ThreadPoolExecutor
-
继承ExecutorService接口
-
作用:调度命令在给定的时间后或定期执行
-
Timer:Timer只创建唯一的线程执行所有任务,耗时的任务会影响其他任务的时效性。且不捕获异常。
-
部分方法
方法名 描述 schedule(Runnable, long, TimeUnit) 在一段时间后执行任务 scheduleAtFixedRate(Runnable, long, long, TimeUnit) 在一段时间后执行并周期执行 scheduleWithFixedDelay(Runnable, long, long, TimeUnit) 在一段时间后执行,并按任务结束后固定时间执行 -
实现类:ScheduledThreadPoolExecutor
-
继承AbstractExecutorService,间接实现ExecutorService接口
-
构造方法的参数
参数 类型 描述 corePoolSize int 核心池大小,工作队列满前的大小 maxPoolSize int 最大池大小,可同时活动线程数上限 keepAliveTime long 存活时间, unit TimeUnit 超过核心池大小的空闲线程被销毁的时间 workQueue BlockingQueue 工作队列,决定了排队方法 threadFactory ThreadFactory (可选)线程工厂,用于创建线程 handler RejectedExecutionHandler (可选)拒绝策略, -
工作队列
- 当线程池线程大于核心线程数,且工作队列未满时,任务会加入工作队列
队列 描述 SynchronousQueue 同步提交队列,没有容量,新任务来时直接创建新线程或执行拒绝策略 ArrayBlockingQueue 有限队列,可指定容量,队列满后可创建新的线程执行队头的任务 linkedBlockingQueue 无限队列,任何任务都可以加入 PriorityBlockingQueue 优先级队列,也是无限 -
线程工厂
- 线程池需要创建线程,通过线程工厂类的newThread()创建一个新的、非守护线程。
- 重写ThreadFacroty类的newThread()方法自定义线程工厂
-
拒绝策略(饱和策略)
- 池中线程数达到最大数量,会执行拒绝策略。
策略 描述 AbortPolicy 默认策略,抛出异常 CallerRunsPolicy 调用者运行,不会丢弃也不会抛异常,在调用者线程执行新任务 DiscardOldestPolicy 遗弃最旧,将最老的任务丢弃,提交新任务 DiscardPolicy 遗弃,放弃任务 - 可以重写RejectedExecutionHandler类的rejectedExecution()方法自定义拒绝策略。
-
代码实现
int corePoolSize = 1; int maxPoolSize = 1; long keepAliveTime = 0L; int capacity = 10; ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(capacity), new ThreadPoolExecutor.DiscardPolicy()); -
构造后再定制属性
方法 描述 setCorePoolSize(int) 设置核心池大小 setMaximumPoolSize(int) 设置最大池大小 setKeepAliveTime(long, TimeUnit) 设置存活时间 setThreadFactory(ThreadFactory) 设置线程工厂 setRejectedeExecutionHandler(RejectedExecutionHandler) 设置拒绝策略 -
监控线程池
方法 返回值 描述 getCorePoolSize() int 核心池大小 getMaximumPoolSize() int 最大池大小 getPoolSize() int 当前池大小 getLargestPoolSize() int 历史最大池大小 getQueue() BlockingQueue 工作队列 getActiveCount() int 当前活动线程数 getCompletedTaskCount() long 完成任务数 getTaskCount long 收到的任务总数 getKeepAliveCount long 存活时间 -
扩展线程池
方法 描述 afterExecute(Runnable, Throwable) 任务结束后会调用 beforeExecute(Runnable, Throwable) 任务执行前会调用 terminated() 线程池完成关闭动作后调用
-
通过静态工厂方法提供预设配置的线程池
-
创建线程方法(返回类型是ExecutorService或ScheduledExecutorService)
方法 描述 newCachedThreadPool() 可缓存的线程池,可灵活回收空闲线程或添加新线程 newFixedThreadPool(int) 定长线程池,每提交一个任务就创建一个线程,直到达到最大池大小 newSingleThreadExecutor() 单线程,只创建一个线程 newScheduledThreadPoll(int) 定长周期线程池
-
接受参数和返回值不同
参数 返回值 参数 返回值 参数 返回值 submit Runnable Future> Runnable,T Future Callable Future execute Runnable void -
处理异常
- 使用submit()提交的任务不会抛出异常,除非使用Future的get()方法
- execute()会抛出异常。
-
Callable与Runnable相似,但是有返回值
-
只有一个方法call(),返回值为类型参数。
public interface Callable
{ V call() throws Exception; }
-
用来保存异步计算的结果
-
接口方法
方法 返回值 描述 get() V 等待计算完成,然后返回结果。被中断会抛中断异常 get(long, TimeUnit) V 在指定时间内完成并返回结果,否则抛出超时异常 cancel(boolean) void 若未开始计算则取消;已经开始计算,可能被中断 isCancelled() boolean 任务在正常完成之前被取消返回true isDone boolean 是否已完成 -
基本实现类是FutureTask,其同时实现了Runnable接口。所以它既可以被线程执行,又可以得到Callable的返回值。
-
代码实现
Callable
myCom = ...; FutureTask task = new FutureTask (myCom); new Thread(task).start(); Integer result = task.get();
-



