手动创建线程池_创建线程池的5个参数

手动创建线程池_创建线程池的5个参数一,Executors类不建议使用自带的工具类的!使用JDK自带的Executors工具类(图中蓝色框中的那个,这是独立于线程池继承关系图的工具类,类似于Collections和Arrays)可以直接创建以下种类的线程池线程数量固定的线程池,此方法返回ThreadPoolExecutorpublicstaticExecutorServicenewFixedThreadPool(intnThreads){……}单线程线程池,此方法返回ThreadPoolExecu

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

一,Executors类

不建议使用自带的工具类的!
使用 JDK 自带的 Executors工具类 (图中蓝色框中的那个,这是独立于线程池继承关系图的工具类,类似于 Collections 和 Arrays) 可以直接创建以下种类的线程池

线程数量固定的线程池,此方法返回
ThreadPoolExecutorpublic static ExecutorService newFixedThreadPool(int nThreads) {… …}
单线程线程池,此方法返回
ThreadPoolExecutorpublic static ExecutorService newSingleThreadExecutor() {… …}
可缓存线程的线程池,此方法返回
ThreadPoolExecutorpublic static ExecutorService newCachedThreadPool() {… …}
执行定时任务的线程池,此方法返回
ScheduledThreadPoolExecutorpublic static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {… …}
可以拆分执行子任务的线程池,此方法返回
ForkJoinPoolpublic static ExecutorService newWorkStealingPool() {… …}

我们可以发现他们得底层实现都是用了ThreadPoolExecutor,然而第五个参数使用到的阻塞队列默认值是Integer.MAX_VALUE,也就是
2147483647,这样就相当于是一个无界的队列。所有的请求都往里塞,最终造成OOM.

二,手动创建线程池

1.常用的线程池实现类是 ThreadPoolExecutor

/** * 各参数含义 * corePoolSize : 线程池中常驻的线程数量。核心线程数,默认情况下核心线程会一直存活,即使处于闲置状态也不会 * 受存活时间 keepAliveTime 的限制,除非将 allowCoreThreadTimeOut 设置为 true。 * maximumPoolSize : 线程池所能容纳的最大线程数。超过这个数的线程将被阻塞。当任务队列为没有设置大小的LinkedBlockingQueue时,这个值无效。 * keepAliveTime : 当线程数量多于 corePoolSize 时,空闲线程的存活时长,超过这个时间就会被回收 * unit : keepAliveTime 的时间单位 * workQueue : 存放待处理任务的队列 * threadFactory : 线程工厂 * handler : 拒绝策略,拒绝无法接收添加的任务 */
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) { 
    ... ... }

2.底层线程池实现的7大参数

corePoolSize:线程池中的常驻核心线程数
maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值必须大于等于1
keepAliveTime:多余的空闲线程的存活时间
unit:keepAliveTime的单位
workQueue:任务队列,被提交但尚未被执行的任务。
threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程一般用默认
handler:拒绝策略,表示当队列满了并且工作线程大于等于线程池的最大线程数

3.工作原理

线程池的底层工作原理core基本线程数,当线程数大于corePoolSize时,多余线程将转入阻塞队列,阻塞队列也满了之后将扩容到maximumPoolSize数。
maximumPoolSize也满了之后将采取拒绝策略。当线程数小了之后,根据设定的空闲线程存活时间将线程总容量回缩到corePoolSize

4,使用可自定义线程名称的线程工厂

4.1,这个就简单多了,可以借助大名鼎鼎的谷歌开源工具库 Guava,首先引入如下依赖:

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>28.2-jre</version>
</dependency>

4.2,自定义实现手动创建线程池

public class ThreadPoolDemo { 
   
// 线程数
    public static final int THREAD_POOL_SIZE = 16;

    public static void main(String[] args) throws InterruptedException { 
   
        // 使用 ThreadFactoryBuilder 创建自定义线程名称的 ThreadFactory
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                .setNameFormat("hyn-demo-pool-%d").build();
        
        // 创建线程池,其中任务队列需要结合实际情况设置合理的容量
        ThreadPoolExecutor executor = new ThreadPoolExecutor(THREAD_P15OOL_SIZE,
                THREAD_POOL_SIZE,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024),
                namedThreadFactory,
                new ThreadPoolExecutor.AbortPolicy());
        
        // 新建 1000 个任务,每个任务是打印当前线程名称
        for (int i = 0; i < 1000; i++) { 
   
            executor.execute(() -> System.out.println(Thread.currentThread().getName()));
        }
        // 优雅关闭线程池
        executor.shutdown();
        executor.awaitTermination(1000L, TimeUnit.SECONDS);
        // 任务执行完毕后打印"Done"
        System.out.println("Done");
    }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187192.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • kafka时间轮源码_flume kafka

    kafka时间轮源码_flume kafkaKafka中存在大量的延迟操作,比如延迟生产、延迟拉取以及延迟删除等。Kafka并没有使用JDK自带的Timer或者DelayQueue来实现延迟的功能,而是基于时间轮自定义了一个用于实现延迟功能的定时器(SystemTimer)。JDK的Timer和DelayQueue插入和删除操作的平均时间复杂度为O(nlog(n)),并不能满足Kafka的高性能要求,而基于时间轮可以将插入和删除操作的时间复…

    2022年10月1日
    5
  • python插值(scipy.interpolate模块的griddata和Rbf)

    python插值(scipy.interpolate模块的griddata和Rbf)1.插值scipy.interpolateSciPy的interpolate模块提供了许多对数据进行插值运算的函数,范围涵盖简单的一维插值到复杂多维插值求解。一维插值:当样本数据变化归因于一个独立的变量时;多维插值:反之样本数据归因于多个独立变量时。注:一维插值这里就不再讲述了,主要是对二维插值的一个总结。2.interp2d()fromscipy.interpolateimportinterp2dinterp2d(x,y,z,kind=’linear’)这里有几个注意事项:

    2022年5月25日
    417
  • mybatis-plus 在线激活码_在线激活

    (mybatis-plus 在线激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月26日
    246
  • 数据库返回的整型数据被偷换成了字符串类型[通俗易懂]

    数据库返回的整型数据被偷换成了字符串类型

    2022年2月15日
    38
  • 关于Random.nextInt()方法详解「建议收藏」

    关于Random.nextInt()方法详解「建议收藏」博主在阅读>这本书时,发现其中有一个使用Random.readInt()的示例,便在idea上敲着看。发现运行结果与书上的一模一样。不禁让我好奇了起来。如下图:                 如果你也照着敲了一遍的话,我相信结果如下:                  问题来了!random.read

    2022年7月22日
    8
  • java8 reduce的用法_Java 8系列之Stream中万能的reduce用法说明

    java8 reduce的用法_Java 8系列之Stream中万能的reduce用法说明reduce操作可以实现从Stream中生成一个值,其生成的值不是随意的,而是根据指定的计算模型。比如,之前提到count、min和max方法,因为常用而被纳入标准库中。事实上,这些方法都是reduce操作。reduce方法有三个override的方法:Optionalreduce(BinaryOperatoraccumulator);Treduce(Tidentity,BinaryO…

    2025年6月18日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号