线程池介绍
在Java中,线程池是一种线程管理的机制,它可以用于管理和调度多个线程,从而避免了频繁创建和销毁线程的开销。Java提供了多种类型的线程池,包括FixedThreadPool、CachedThreadPool、SingleThreadExecutor等等,每种线程池都有自己的特点和适用场景。
线程池的主要作用是将多个任务分配给多个线程并发执行,从而提高程序的性能和效率。线程池通常包括以下几个部分:
任务队列:用于存储待执行的任务。
线程池管理器:用于管理线程池中的线程,包括创建和销毁线程等操作。
工作线程:执行任务的线程。
Java中的线程池通常包括以下几种类型:
FixedThreadPool:固定大小的线程池,线程数量固定,不会发生变化,适用于执行长期的任务。
CachedThreadPool:可缓存的线程池,线程数量不固定,根据任务的数量自动创建和销毁线程,适用于执行短期的任务。
SingleThreadExecutor:单线程的线程池,只有一个工作线程,适用于需要按顺序执行任务的场景。
ScheduledThreadPool:可调度的线程池,可以按照一定的时间间隔执行任务。
WorkStealingPool:工作窃取线程池,采用分治的策略,将任务分割成多个子任务,然后交给空闲的线程执行,可以提高程序的并发性能。
需要注意的是,线程池的使用需要根据具体的场景进行选择,不同类型的线程池适用于不同类型的任务。在使用线程池时,需要考虑线程池的大小、任务队列的大小、任务的类型和执行时间等因素,以确保线程池的性能和稳定性。
线程池创建方式
线程池创建有七种方式:
newSingleThreadExecutor():它的特点在于工作线程数目被限制为 1,操作一个无界的工作队列,所以它保证了所有任务的都是被顺序执行,最多会有一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免其改变线程数目;
newCachedThreadPool():它是一种用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用,当无缓存线程可用时,就会创建新的工作线程;如果线程闲置的时间超过 60 秒,则被终止并移出缓存;长时间闲置时,这种线程池,不会消耗什么资源。其内部使用 SynchronousQueue 作为工作队列;
newFixedThreadPool(int nThreads):重用指定数目(nThreads)的线程,其背后使用的是无界的工作队列,任何时候最多有 nThreads 个工作线程是活动的。这意味着,如果任务数量超过了活动队列数目,将在工作队列中等待空闲线程出现;如果有工作线程退出,将会有新的工作线程被创建,以补足指定的数目 nThreads;
newSingleThreadScheduledExecutor():创建单线程池,返回 ScheduledExecutorService,可以进行定时或周期性的工作调度;
newScheduledThreadPool(int corePoolSize):和newSingleThreadScheduledExecutor()类似,创建的是个 ScheduledExecutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多个工作线程;
newWorkStealingPool(int parallelism):这是一个经常被人忽略的线程池,Java 8 才加入这个创建方法,其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序;
ThreadPoolExecutor():是最原始的线程池创建,上面1-3创建方式都是对ThreadPoolExecutor的封装。