Java基础知识-Java线程池

 2024-01-13 03:03:37  阅读 0

概念

线程池实际上是一个维护很多线程的池。 类似的池化技术还有很多,比如:连接池、数据库连接池、内存池等。

线程池的优点

Java并发编程框架中的线程池是应用最广泛的技术。 几乎所有需要异步或并发执行任务的程序都可以使用线程池。 在开发过程中,合理使用线程池至少可以带来以下四个好处:

减少资源消耗。 通过复用已创建的线程,减少线程创建和销毁带来的消耗; 提高响应速度。 当任务到达时,可以立即执行任务,无需等待线程创建,提高线程的可管理性。 线程是稀缺资源。 如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性。 线程池可用于统一分配、调优和监控。 提供更强大的功能。例如延迟定时线程池; 线程池的实现原理

当用户向线程池提交任务时,线程池会这样执行:

首先判断核心线程数是否满。 如果未满,则创建一个线程来执行任务; 如果线程池中的核心线程数已满,则继续判断任务队列是否已满。 如果未满,则将任务放入任务队列即可。 如果任务队列已满,则判断线程池是否已满。 如果未满,则创建一个线程来执行任务; 如果线程池已满,则根据拒绝策略做出决定。 对应加工等级

在我们的日常开发中,线程池的使用基本上都是基于类的。 它的继承体系是这样的:

-> 冰->->

施工方法

public  class  ThreadPoolExecutor  extends  AbstractExecutorService {
    ......
    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler) {
            if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0){
                throw new IllegalArgumentException();
            }
            if (workQueue == null || threadFactory == null || handler == null){
                throw new NullPointerException();
            }
            this.acc = System.getSecurityManager() == null ? null : AccessController.getContext();
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.workQueue = workQueue;
            this.keepAliveTime = unit.toNanos(keepAliveTime);
            this.threadFactory = threadFactory;
            this.handler = handler;
        }
}

主要参数如下:

:线程池工厂,主要用于给线程一个标识。 即给线程起一个有意义的名字;

: 拒绝政策

提交任务到线程池

向线程池提交任务有两种方法,分别是 和 。

方法

()方法用于提交不需要返回值的任务,因此无法判断任务是否被线程池成功执行。

()方法输入的任务是一个类的实例。

空白 ( );

executorService.execute(()->{
            System.out.println("ThreadPoolDemo.execute");
        });

方法

()方法用于提交需要返回值的任务。

(任务);

线程池会返回一个类型的对象,通过该对象可以判断任务是否执行成功,并可以通过get()方法获取返回值。 get()方法会阻塞当前线程直到任务完成,而使用get(long,unit)方法会阻塞当前线程一段时间并立即返回。 这个时候,任务可能还没有完成。

Future<?> submit = executorService.submit(() -> {
            System.out.println("ThreadPoolDemo.submit");
        });

关闭线程池

通过调用线程池的 or 方法关闭线程池

它们的原理是遍历线程池中的工作线程,然后一一调用线程方法来中断线程(PS:中断只是标记线程,并不代表线程已经停止,如果线程没有停止)响应中断,则该标记将不起作用),因此无法响应中断的任务可能永远不会终止。

但它们之间也存在一定的差异。 首先将线程池的状态设置为STOP,然后尝试停止所有正在执行或挂起任务的线程,并返回等待执行的任务列表,但只需将线程池的状态设置为,然后中断所有未执行任务的线程。

只要调用这两个关闭方法中的任何一个,该方法都会返回 true。 当所有任务都已经关闭后,就表示线程池关闭成功,调用方法会返回true。 至于应该调用哪个方法来关闭线程池,应该根据提交到线程池的任务的特性来确定。 通常会调用一个方法来关闭线程池。 如果任务不必完成,则可以调用一个方法。

线程池状态 线程池有5种状态,STOP, , ,

3. 状态说明

为线程池设置合理的参数

设置参数一般取决于以下几点:

不同性质的任务可以使用不同大小的线程池分别处理。 分为CPU密集型和IO密集型。

类创建线程池

它是Java中的一个工具类。 提供工厂方法来创建不同类型的线程池。

(int):创建一个固定线程数的线程池。 ():创建一个可缓存的线程池,调用将重用之前构造的线程(如果线程可用)。 如果没有可用线程,则会创建一个新线程并将其添加到池中。 终止并从缓存中删除那些 60 秒未使用的线程。 tor() 创建一个单线程。 ol(int) 创建一个支持计划和周期性任务执行的线程池,在大多数情况下可以用来替换 Timer 类。

该类看上去功能比较强大,采用工厂模式,扩展性比较强。 重要的是使用起来比较方便,比如:

=.();

创建线程池的问题

阿里巴巴Java开发手册中明确规定,不允许创建线程池。

使用ol运行时创建的线程数是。 可能会创建大量线程,导致OOM总结

线程池执行图

补充一下常用的队列,线程池中常用的方法有,队列如下:

标签: 线程 任务 创建

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码