线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。

    Executors.newCacheThreadPool():可缓存线程池,先查看池中有没有以前建立的线程,如果有,就直接使用。如果没有,就建一个新的线程加入池中,缓存型池子通常用于执行一些生存期很短的异步型任务
    Executors.newFixedThreadPool(int n):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程。
    Executors.newScheduledThreadPool(int n):创建一个定长线程池,支持定时及周期性任务执行
    Executors.newSingleThreadExecutor():创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
    (1)、降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;
    (2)、提高系统响应速度,当有任务到达时,通过复用已存在的线程,无需等待新线程的创建便能立即执行;
    (3)方便线程并发数的管控。因为线程若是无限制的创建,可能会导致内存占用过多而产生OOM,并且会造成cpu过度切换(cpu切换线程是有时间成本的(需要保持当前执行线程的现场,并恢复要执行线程的现场))。
    (4)、提供更强大的功能,延时定时线程池。

    为什么要使用线程池?
    假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。如果:T1 + T3 远大于 T2,那么系统的大部分时间都花在了创建和销毁上,造成性能上的浪费。而如果并发的线程数量很多,如果允许所有并发请求都通过创建新线程来处理,那么这时候我们没有限制系统内的并发执行线程的数量,无限制的线程可能耗尽系统资源,如 CPU 时间和内存。并且如果每个线程都是执行一个时间很短的任务就结束了,那么频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。此时我们就可以使用线程池技术。

    什么情况下使用线程池?
    1、单个任务处理时间比较短

    2、处理任务数量大

    线程池改进了一个应用程序的响应时间。由于线程池中的线程已经准备好且等待被分配任务,应用程序可以直接拿来使用而不用新建一个线程。
    线程池节省了CLR 为每个短生存周期任务创建一个完整的线程的开销并可以在任务完成后回收资源。
    线程池根据当前在系统中运行的进程来优化线程时间片。
    线程池允许我们开启多个任务而不用为每个线程设置属性。
    线程池允许我们为正在执行的任务的程序参数传递一个包含状态信息的对象引用。
    线程池可以用来解决处理一个特定请求最大线程数量限制问题。