在开发多线程应用程序时,我们通常必须处理组织线程的工作。我们的应用程序越大,多线程任务所需的线程越多,可运行我们创建的对象。

这里需要注意的是,在 Java 中创建线程是一个相当昂贵的操作。如果我们每次都创建一个线程的新实例来执行一个操作,我们会在性能上遇到很大的问题,结果会影响应用程序的健康。

线程ThreadPoolExecutor在这里为我们提供帮助。

线程是一组预先初始化的线程。它的大小可以是固定的或可变的。

如果任务多于线程,则任务在任务队列中等待。池中的第 N 个线程从队列中取出一个任务,完成后,该线程从队列中取出一个新任务。一旦队列中的所有任务都执行完毕,线程将保持活动状态并等待新任务。当新任务出现时,线程也开始执行它们。

线程池执行器

从 Java 5 开始,Executor 框架获得了多线程解决方案。总的来说,它有很多组件,目的是帮助我们高效地管理队列和线程池。

主要接口是ExecutorExecutorService

Executor是具有单个 void execute(Runnable runnable) 方法的接口。

将任务传递给此方法的实现时,知道它将来会异步执行。

ExecutorService — 扩展Executor接口的接口,添加执行任务的功能。它还具有中断正在运行的任务和终止线程池的方法。

ThreadPoolExecutor实现了ExecutorExecutorService接口,将任务创建和任务执行分开。我们需要实现Runnable对象并将它们发送给执行程序。然后ThreadPoolExecutor负责执行任务,创建和使用线程

发送任务执行后,将使用池中的现有线程。这提高了性能。它解决了在创建和初始化新线程时浪费资源的问题,然后在我们完成线程后再次在垃圾收集上浪费资源。

ThreadPoolExecutor有 4 个构造函数:


ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit, 
BlockingQueue<Runnable> workQueue)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
    

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

ThreadPoolExecutor构造函数具有以下参数:

核心池大小 该参数表示执行器服务启动时将准备好(启动)多少个线程。
最大池大小 执行程序服务可以创建的最大线程数。
保活时间 如果线程数大于,则释放的线程在被销毁之前将继续存在的时间核心池大小. 时间单位在下一个参数中指定。
单元 时间单位(小时、分钟、秒、毫秒等)。
工作队列 任务队列的实现。
处理程序 无法完成的任务的处理程序。
线程工厂 按需创建新线程的对象。使用线程工厂使得对新线程的调用与硬件无关,允许应用程序使用特殊的线程子类、优先级等。

创建线程池执行器

Executors实用程序类可以简化ThreadPoolExecutor的创建。这个实用类的方法帮助我们准备一个线程池执行器目的。

newFixedThreadPool — 创建一个线程池,重复使用固定数量的线程来执行任意数量的任务。

ExecutorService executor = Executors.newFixedThreadPool(10);
                    
newWorkStealingPool — 创建一个线程池,其中线程数等于 JVM 可用的处理器内核数。默认并发级别为 1。这意味着将在池中创建与 JVM 可用的 CPU 内核一样多的线程。如果并发级别为 4,则使用传递的值而不是核心数。

ExecutorService executor = Executors.newWorkStealingPool(4);
                    
newSingleThreadExecutor — 创建一个具有单个线程的池来执行所有任务。

ExecutorService executor = Executors.newSingleThreadExecutor();
                    
newCachedThreadPool — 创建一个线程池,根据需要创建新线程,但在可用时重用以前创建的线程。

ExecutorService executor = Executors.newCachedThreadPool();
                    
newScheduledThreadPool — 创建一个线程池,可以安排命令在给定延迟后或定期执行。

ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
                    

我们将在以下课程中考虑每种类型的游泳池。