总结一下线程池

一、线程池的优点和处理流程

1、优点

  • 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  • 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
  • 提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。

2、处理流程

总结一下线程池

二、扩展知识

1、corePoolSize和maximumPoolSize可以在创建之后使用setCorePoolSize()、setMaximumPoolSize()进行改变。

2、核心线程默认是第一个任务到达时创建的,但是可以通过prestartCoreThread()、prestartAllCoreThreads()覆盖进行提前创建(传入一个非空队列时可使用)。

3、默认的ThreadFactory使用相同的ThreadGroup、相同的NORM_PRIORITY和non-daemon status创建线程,你可以使用自定义线程工厂修改线程名称、组、优先级、守护状态。创建线程失败newThread()返回null时,执行器继续工作,但是可能不会执行任务。

4、超出corePoolSize的额外线程(即非核心线程)如果它们空闲时间超过了keepAliveTime之后会被终止。可以通过allowCoreThreadTimeOut(boolean)让核心线程也会被超时回收。

5、队列的策略通常三种

直接传递:SynchronousQueue(通常要求maximumPoolSizes*避免新任务被拒绝)。

*:LinkedBlockingQueue(maximumPoolSize没有效果,不会创建非核心线程)。

有界:ArrayBlockingQueue(大队列少线程可以最小化CPU使用率、OS资源和上下文切换,但是会降低吞吐量。如果任务频繁阻塞,可以分配更多线程。小队列多线程可以保持CPU繁忙但是会带来更多的调度开销,也可能降低吞吐量)。

6、拒绝策略

AbortPolicy:默认的,抛出RejectedExecutionException。

CallerRunsPolicy:调用execute()的线程执行,可以提供简单反馈控制但是减缓任务提交速度。

DiscardPolicy:丢弃任务。

DiscardOldestPolicy:先丢掉队列首部任务,再execute,再次失败时将导致重复。

7、钩子方法

beforeExecute(Thread, Runnable)和afterExecute(Runnable, Throwable)会在每个任务execute之前和之后被调用,可以用来做一些监控或者日志记录等。钩子方法抛出异常可能导致线程失败或终止。

8、可以使用getQueue()获取任务队列然后remove/purge做一些任务回收管理。

9、程序不在引用并且没有存活线程的pool将会自动shutdown。

10、线程池运行状态(跟线程状态是两个概念哈)

RUNNING: Accept new tasks and process queued tasks

SHUTDOWN: Don't accept new tasks, but process queued tasks

STOP: Don't accept new tasks, don't process queued tasks, and interrupt in-progress tasks

TIDYING: All tasks have terminated, workerCount is zero, the thread transitioning to state TIDYING will run the terminated() hook method

TERMINATED: terminated() has completed

11、线程池运行状态转换图(跟线程状态转换图是两个概念哈)

总结一下线程池

上一篇:[mysql] mysqldump导出指定数据库表和条件的数据


下一篇:线程池提交任务方法