工作生活

线程池,使用ThreadPoolExecutor代替Execut

2019-07-04  本文已影响0人  撸完代码送快递
image.png

合理使用线程池的好处:

Executor架构

image.png

在HotSpot虚拟机中,Java中的线程将会被一一映射为操作系统的线程 在Java虚拟机层面,用户将多个任务提交给Executor框架,Executor负责分配线程执行它们; 在操作系统层面,操作系统再将这些线程分配给处理器执行


image.png

Executor框架中的所有类可以分成三类:
1.任务 任务有两种类型:Runnable和Callable。
2.任务执行器 Executor框架最核心的接口是Executor,它表示任务的执行器。
Executor的子接口为ExecutorService。
ExecutorService有两大实现类:ThreadPoolExecutor和ScheduledThreadPoolExecutor。
3.执行结果
Future接口表示异步的执行结果,它的实现类为FutureTask。

ThreadPoolExecutor类

image.png

Executor接口

Executor接口只有一个execute方法,用来替代通常创建或启动线程的方法。

ExecutorService接口

ExecutorService接口继承自Executor接口,提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。增加了shutDown(),shutDownNow(),invokeAll(),invokeAny()和submit()等方法。如果需要支持即时关闭,也就是shutDownNow()方法,则任务需要正确处理中断。

AbstractExecutorService抽象类

提供ExecutorService接口的默认实现方法。

创建线程池的方法

ExecutorService threadPool = new ThreadPoolExecutor(1, 5, 30, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<Runnable>(1024), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());

其中线程工厂可以使用guava包中的方法创建:

ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();

参数说明:

线程池规则:
1.如果线程数量<=核心线程数量,那么直接启动一个核心线程来执行任务,不会放入队列中。
2.如果线程数量>核心线程数,但<=最大线程数,并且任务队列是LinkedBlockingDeque的时候,超过核心线程数量的任务会放在任务队列中排队。
3.如果线程数量>核心线程数,但<=最大线程数,并且任务队列是SynchronousQueue的时候,线程池会创建新线程执行任务,这些任务也不会被放在任务队列中。这些线程属于非核心线程,在任务完成后,闲置时间达到了超时时间就会被清除。
4.如果线程数量>核心线程数,并且>最大线程数,当任务队列是LinkedBlockingDeque,会将超过核心线程的任务放在任务队列中排队。也就是当任务队列是LinkedBlockingDeque并且没有大小限制时,线程池的最大线程数设置是无效的,他的线程数最多不会超过核心线程数。
5.如果线程数量>核心线程数,并且>最大线程数,当任务队列是SynchronousQueue的时候,会因为线程池拒绝添加任务而抛出异常。


image.png

使coreThread失效

之前设置的keepAliveTime参数只能使超过此阈值的非核心线程失效,使用allowCoreThreadTimeOut(boolean value)方法将allowCoreThreadTimeOut设置为true则可以将该策略应用于核心线程。

http://www.ideabuffer.cn/2017/04/04/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E7%BA%BF%E7%A8%8B%E6%B1%A0%EF%BC%9AThreadPoolExecutor/
https://blog.csdn.net/z_s_z2016/article/details/81674893

上一篇下一篇

猜你喜欢

热点阅读