如何实现一个线程池

Wenhao 6月前 ⋅ 73 阅读

阿里巴巴Java开发手册》中强制线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险

Executors 返回线程池对象的弊端如下: FixedThreadPool 和 SingleThreadExecutor : 允许请求的队列长度为 Integer.MAX_VALUE ,可能堆积大量的请求,从而导致OOM。 CachedThreadPool 和 ScheduledThreadPool : 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致OOM。 使用线程池就是为了降低资源消耗、提高响应速度、提高线程的可管理性

实现线程池有两种方式: 方式一 通过构造方法实现 方式二 通过Executor框架的工具类Executors实现 我们可以创建四种类型的ThreadPoolExecutor FixedThreadPool :该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务 SingleThreadExecutor:方法返回一个只有一个线程的线程池,若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务 CachedThreadPool:该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可服用线程,若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行服用 ScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行

线程池的七个重要参数: 1.核心线程数:核心线程数线程数定义了最小可以同时运行的线程数量。 2.最大线程数:当队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。 3.阻塞队列:当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,信任就会被存放在队列中。 4.线程存活时间:当线程池中的线程数量大于 corePoolSize 的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 5.时间单位:线程存活时间的时间单位。 6.线程工厂:executor 创建新线程的时候会用到。 7.拒绝策略: ●ThreadPoolExecutor.AbortPolicy:抛出 RejectedExecutionException来拒绝新任务的处理。 ●ThreadPoolExecutor.CallerRunsPolicy:调用执行自己的线程运行任务。您不会任务请求。但是这种策略会降低对于新任务提交速度,影响程序的整体性能。另外,这个策略喜欢增加队列容量。如果您的应用程序可以承受此延迟并且你不能任务丢弃任何一个任务请求的话,你可以选择这个策略。 ●ThreadPoolExecutor.DiscardPolicy: 不处理新任务,直接丢弃掉。 ●ThreadPoolExecutor.DiscardOldestPolicy: 此策略将丢弃最早的未处理的任务请求。


全部评论: 0

    我有话说: