目录

使用线程池的原因核心类分类执行和取消,有无返回值优缺点线程池工具类,直接使用

一、使用线程池的原因

  • 线程的创建和销毁都需要时间,当有大量的线程创建和销毁时,那么这些时间的消耗则比较明显,将会导致性能上的缺失。
  • 大量的线程创建、执行和销毁非常耗CPU和内存,这样将直接影响系统的吞吐量,导致性能急剧下降,如果内存资源占用的比较多,还可能造成OOM。
  • 大量线程的创建和销毁很容易导致GC频繁执行,从而发生内存抖动现象,对于移动端来说,最直观的体现就是造成界面卡顿。

二、核心类

线程池指的是ThreadPoolExecutor,它实现了ExecutorService接口,并封装了一系列的api使得它具有线程池的特性,其中包括工作队列、核心线程数、最大线程数等。

public ThreadPoolExecutor(int corePoolSize, 
						  int maximumPoolSize, 
						  long keepAliveTime, 
						  TimeUnit unit, 
						  BlockingQueue<Runnable> workQueue, 
						  ThreadFactory threadFactory, 
						  RejectedExecutionHandler handler) {...}

三、线程池分类

阿里巴巴推荐使用ThreadPoolExecutor创建线程池,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。Executors类是官方提供的一个工厂类,里面封装了许多功能不一的线程池,主要包括以下五种线程池

newFixedThreadPool()


作用:该方法返回一个固定线程数量的线程池,该线程池中的线程数量始终不变,即不会再创建新的线程,也不会销毁已经创建好的线程,自始至终都是那几个固定的线程在工作,所以该线程池可以控制线程的最大并发数。
例子:假如有一个新任务提交时,如果线程池中有空闲的线程,则立即使用空线程来处理任务,如果没有,则会把这个新任务存放在一个任务队列中,一旦有线程空闲,则按FIFO方式处理任务队列中的任务。

newCachedThreadPool()


作用:该方法返回一个可以根据实际情况调整线程池中线程数量的线程池。即该线程池中的线程数量不确定,是根据实际情况动态调整的。
例子:假如线程池中的所有线程都正在工作,而此时有新任务提交,那么将会创建新线程去处理该任务,而此时假如之前有一些线程完成了任务,现在又有新任务提交,那么将不会创建新线程去处理,而是复用空闲的线程去处理新任务。那么此时可能有人会有疑问,如果这样,该线程池的线程岂不是越来越多?其实并不会,因为线程池中的线程都有个“保持活动时间”参数,通过配置它,如果线程池中的空闲线程的空闲时间超过该“保持活动时间”,则立即销毁该线程,而该线程池默认的“保持活动时间”为60s。

newSingleThreadExecutor()


作用:该方法返回一个只用一个线程的线程池,即每次只执行一个线程任务,多余的任务会保存到一个任务队列中,等待这个线程空闲,然后再按照FIFO方式顺序执行任务队列中的任务。

newScheduledThreadPool()


作用:该方法返回一个可以控制线程池内线程定时或周期性执行某任务的线程池。

newSingleThreadScheduledExecutor()


作用:该方法返回一个可以控制线程池内线程定时或周期性执行某任务的线程池。只不过和上面的区别是,该线程池的大小为1,而上面的可以指定线程池的大小。

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
ScheduledExecutorService singleThreadScheduledPool = Executors.newSingleThreadScheduledExecutor();

四、执行和取消

五、优缺点

  • 节约线程创建和销毁的开销;
  • 通过复用线程,提高了系统响应速度;
  • 方便线程并发数的管控;
  • 提供延时定时任务;
  • 如果线程池存在阻塞,则会影响程序执行;