手动创建线程池_创建线程池的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)
上一篇 2022年10月1日 上午10:00
下一篇 2022年10月1日 上午10:16


相关推荐

  • python的取余算法原理_python.取余算法

    python的取余算法原理_python.取余算法#-*-coding:utf-8-*-”’Createdon2012-12-28取余。取一个任意小于1美元的金额,然后计算可以换成最少多少枚硬币。硬币有1美分,5美分,10美分,25美分四种。1美元等于100美分。举例来说,0.76美元换算结果应该是3枚25美分,1枚1美分。类似76枚1美分,2枚25美分+2枚10美分+1枚5美分+1枚1美分这样的…

    2022年4月25日
    46
  • 如何学习PLC编程「建议收藏」

    如何学习PLC编程「建议收藏」plc是工业常用的自动化产品可编程控制器,它就相当于人类的大脑控制其他的器官,可编程控制器说白了就是个CPU,带几个模块,模块功能主要是,模拟量输入输出,数字量输入输出,其他功能计数模块。PLC在工业领域里扮演着重要的角色,作为一家企业或者个人应如何学习PLC呢?1.有一定的电工基础,掌握传感器、接近开关、编马器、气动元件等常用器件的使用及继电器控制原理。2.再学数制及数制转换,掌握二进制、八进制、十六进制、BCD码、ASCI码的概念。3.选择你所在地区流型的PLC品牌做为学习的机种,学会后可以更

    2022年10月19日
    5
  • 我用OpenClaw,5分钟写出一个skill的7个步骤(第三讲,思路通用)

    我用OpenClaw,5分钟写出一个skill的7个步骤(第三讲,思路通用)

    2026年3月13日
    3
  • swagger常用注解[通俗易懂]

    一、swagger常用注解1、与模型相关的注解两个注解:@ApiModel:用在模型类上,对模型类做注释;@ApiModelProperty:用在属性上,对属性做注释2、与接口相关的注解六个注解:@Api:用在controller上,对controller进行注释;@ApiOperation:用在API方法上,对该API做注释,说明API的作用;

    2022年4月14日
    57
  • 数字化转型中的大数据治理架构

    数字化转型中的大数据治理架构一、数字化时代大数据向服务化发展数字化时代,我们的数据来源比以前更广了。第一,之前传统企业政府的IT系统主要是面向内部使用,产生了一些信息,现在已经面向外部使用了;第二,更多行为信息、社交信息都会变成企业的数据;第三,我们有很多非结构化的数据,比如媒体、视频数据等;第四,还有物联网传感器方面的数据等。这些数据大部分是非结构化的,如媒体数据、视频数据,包括物联网传感器等信息,这些信息远比以前更加难以…

    2025年8月13日
    3
  • 1、基于MFC的OpenGL程序

    1、基于MFC的OpenGL程序

    2021年11月19日
    49

发表回复

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

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