- 线程生命周期的开销(创建和关闭线程等开销)
- 活动线程消耗系统资源,大量空闲线程占用更多内存,给垃圾回收器带来压力。
- 过多的线程会影响稳定性,甚至拖垮程序。
过程:线程池管理一个工作者线程的同构池,并与工作队列绑定。它从工作队列中获取下一个任务并执行。
优点:
-
可以重用线程,减少创建和关闭线程的开销。
-
提高响应性,不需要创建线程也就不会延迟任务的执行。
-
通过调整线程池大小,可以保持处理器忙碌的同时防止过多线程竞争资源(耗尽内存)。
-
对于计算密集型任务,线程数为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接口
-
构造方法的参数
参数 类型 描述 corePoolSizeint核心池大小,工作队列满前的大小 maxPoolSizeint最大池大小,可同时活动线程数上限 keepAliveTimelong存活时间, unitTimeUnit超过核心池大小的空闲线程被销毁的时间 workQueueBlockingQueue 工作队列,决定了排队方法 threadFactoryThreadFactory(可选)线程工厂,用于创建线程 handlerRejectedExecutionHandler(可选)拒绝策略, -
工作队列
- 当线程池线程大于核心线程数,且工作队列未满时,任务会加入工作队列
队列 描述 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完成任务数 getTaskCountlong收到的任务总数 getKeepAliveCountlong存活时间 -
扩展线程池
方法 描述 afterExecute(Runnable, Throwable)任务结束后会调用 beforeExecute(Runnable, Throwable)任务执行前会调用 terminated()线程池完成关闭动作后调用
-
通过静态工厂方法提供预设配置的线程池
-
创建线程方法(返回类型是ExecutorService或ScheduledExecutorService)
方法 描述 newCachedThreadPool()可缓存的线程池,可灵活回收空闲线程或添加新线程 newFixedThreadPool(int)定长线程池,每提交一个任务就创建一个线程,直到达到最大池大小 newSingleThreadExecutor()单线程,只创建一个线程 newScheduledThreadPoll(int)定长周期线程池
-
接受参数和返回值不同
参数 返回值 参数 返回值 参数 返回值 submitRunnableFuture>Runnable,T Future Callable Future executeRunnablevoid -
处理异常
- 使用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 isDoneboolean是否已完成 -
基本实现类是FutureTask,其同时实现了Runnable接口。所以它既可以被线程执行,又可以得到Callable的返回值。
-
代码实现
Callable
myCom = ...; FutureTask task = new FutureTask (myCom); new Thread(task).start(); Integer result = task.get();
-
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)