java学习之线程池

java线程池优点:

  1. 降低线程创建和销毁的开销,提高系统性能。

  2. 提高线程的利用率和系统的吞吐量。

  3. 统一线程的管理和监控,避免线程泄漏和线程安全问题。

  4. 支持任务队列和拒绝策略等机制,提供灵活的任务调度和任务处理能力。

并不是所有的业务场景都需要线程池,因为线程池中会涉及到调度相关的内容,如果业务量非常少,并且应用了线程池,可能会导致性能降低。

一、ThreadPoolExecutor线程池实例构造函数如下:

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.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

corePoolSize:核心线程数,提交任务后首先通过核心线程执行任务,当核心线程数达到corePoolSize值的时候,会开辟新的线程执行任务。一般来说核心线程数设置的值为CPU核数,具体情况根据具体的业务来分析。

maximumPoolSize:最大线程数,包括核心线程和非核心线程。

keepAliveTime:非核心线程存活时间,当核心线程数能够执行当前任务时,非核心线程处于空闲状态,但是并不会立马消失,如果设置存活时间,则会等存活时间过之后会被回收。

unit:keepAliveTime的单位,主要包括DAYS:时间单位代表二十四小时;HOURS:时间单位代表六十分钟;MICROSECONDS:时间单位代表千分之一毫秒;MILLISECONDS:时间单位为千分之一秒;MINUTES:时间单位代表6o秒;NANOSECONDS:时间单位代表千分之一千分之一;SECONDS:时间单位代表一秒。

workQueue:存储等待执行任务的队列。

threadFactory:线程工厂,用于创建线程。

handler:拒绝策略,主要包含以下几种。

1、默认的策略:直接抛出异常

public static class AbortPolicy implements RejectedExecutionHandler {
    public AbortPolicy() { }
​
    /**
     * Always throws RejectedExecutionException.
     *
     * @param r the runnable task requested to be executed
     * @param e the executor attempting to execute this task
     * @throws RejectedExecutionException always
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        throw new RejectedExecutionException("Task " + r.toString() +
                                             " rejected from " +
                                             e.toString());
    }
}

2、直接由提交任务的线程执行任务,不用去到队列中

public static class CallerRunsPolicy implements RejectedExecutionHandler {
    public CallerRunsPolicy() { }
​
    /**
     * Executes task r in the caller's thread, unless the executor
     * has been shut down, in which case the task is discarded.
     *
     * @param r the runnable task requested to be executed
     * @param e the executor attempting to execute this task
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            // 直接通过r来执行任务
            r.run();
        }
    }
}

3、丢弃掉阻塞队列中最靠前的任务

public static class DiscardOldestPolicy implements RejectedExecutionHandler {
    public DiscardOldestPolicy() { }
​
    /**
     * Obtains and ignores the next task that the executor
     * would otherwise execute, if one is immediately available,
     * and then retries execution of task r, unless the executor
     * is shut down, in which case task r is instead discarded.
     *
     * @param r the runnable task requested to be executed
     * @param e the executor attempting to execute this task
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            // 返回队里中的头部元素
            e.getQueue().poll();
            e.execute(r);
        }
    }
}

4、丢弃掉当前任务

public static class DiscardPolicy implements RejectedExecutionHandler {
    public DiscardPolicy() { }
​
    /**
     * Does nothing, which has the effect of discarding task r.
     *
     * @param r the runnable task requested to be executed
     * @param e the executor attempting to execute this task
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    }
}

二、线程池的相关状态

RUNNING:线程池运行状态,可以接收新的任务,并且可以处理阻塞队列中的任务。

SHUTDOWN:关闭状态,关闭意味着不会去接收新的任务,但是可以处理阻塞队列中已经存在的任务。

STOP:线程池处于停止状态,不会接收新的任务,同时也不会再执行阻塞队列中已经存在的任务。

TIDYING:所有的任务执行完成或者被终止处于该状态。

TERMINATED:当所有的任务终止或者被执行完毕的时候,所有的线程被清空的时候,线程池会处于该状态。

执行线程的方法:execute(),submit(),shutdown(),shutdownNow()

三、创建线程也可以使用Executors类,可以创建不同的线程池,比如:

  1. newFixedThreadPool(int nThreads): 创建一个固定大小的线程池。

  2. newCachedThreadPool(): 创建一个可缓存的线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

  3. newSingleThreadExecutor(): 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证按提交顺序执行。

  4. newScheduledThreadPool(int corePoolSize): 创建一个固定大小的线程池,可以在给定的延迟后执行或定期执行任务。

  5. newSingleThreadScheduledExecutor(): 创建一个单线程化的线程池,可以在给定的延迟后执行或定期执行任务。

通过此方法创建的线程池返回的也是ThreadPoolExecutor对象,只是给定了相关的参数,比如newCachedThreadPool源码如下:

public static ExecutorService newCachedThreadPool() {
    // 返回ThreadPoolExecutor对象
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

newScheduledThreadPool线程池可以通过调度的方式进行执行,示例如下:

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
// 可以设置延迟几秒后执行任务
scheduledExecutorService.schedule(new Runnable() {
    @Override
    public void run() {
        log.info("任务执行");
    }
},2, TimeUnit.SECONDS);
​
// 间隔一秒 每三秒执行一次
/**
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit);
*/
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        log.info("任务执行");
    }
},1,3,TimeUnit.SECONDS);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/522690.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【网络安全之渗透测试】公开课-即将开始

​4月13日&#xff0c;下午一点&#xff0c;网络安全-渗透公开课&#xff0c;感兴趣的可以留言免费参加 &#x1f525;&#x1f525;&#x1f525;大新闻来啦&#xff01;各位网络安全爱好者、IT从业者、或者是想要保护自己的数字生活的小伙伴们&#xff0c;注意了&#xff01;…

利驰软件荣获2023年度中国智能制造优秀供应商及优秀推荐产品奖

2024年3月28-29日&#xff0c;由e-works数字化企业网主办的“第十三届中国智能制造高峰论坛暨第二十一届中国智能制造岁末盘点颁奖典礼”于北京西南华邑酒店召开。 大会邀请了中国工程院院士、阿里研究院副院长、国家智能制造专家委员会委员等行业专家&#xff0c;以及国内外知…

银行ITSS体系下低代码运维体系实践分享

前言 自2021年中国人民银行发布《金融科技发展规划&#xff08;2022-2025年&#xff09;》以来&#xff0c;商业银行迈入数字化转型的高阶阶段。在此背景下&#xff0c;为了进一步提高金融科技的管理水平&#xff0c;商业银行需要改变传统金融运维模式&#xff0c;对已有运维体…

Web漏洞-文件上传常见验证

后缀名&#xff1a;类型&#xff0c;文件头等 后缀名&#xff1a;黑白名单 文件类型&#xff1a;MIME信息 文件头&#xff1a;内容头信息 常见黑名单&#xff08;明确不允许上传的格式后缀&#xff09;&#xff1a;asp、php、jsp、aspx、cgi、war &#xff08;如果没有完整…

Retrofit2 完全解析 探索与okhttp之间的关系

//用于访问zhy的信息 http://192.168.1.102:8080/springmvc_users/user/zhy //用于访问lmj的信息 http://192.168.1.102:8080/springmvc_users/user/lmj 即通过不同的username访问不同用户的信息&#xff0c;返回数据为json字符串。 那么可以通过retrofit提供的PATH注解非…

Java文件流操作

一、文件创建和删除 public static void main(String[] args) throws IOException {File file new File("..\\hello-world.txt");//..表示在上机目录下创建hello-world.txtSystem.out.println(file.getPath());//返回当前相对路径System.out.println(file.getCanoni…

电商技术揭秘十二:电商平台的搜索引擎优化与营销小结

相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xff1a;电商平台…

图像分割 - 利用K-means聚类方法实现图像分割

1、前言 传统的数字图像处理算法中,针对于图像分割部分,除了阈值处理、区域生长啊等等之类的,还有很经典的聚类算法 图像分割是指将图像划分为多个片段。这是因为对于不同的图像任务,我们往往不care整个图片,只对感兴趣的区域处理,这就是图像分割的意义。 聚类算法的思…

2024.4.6-day11-CSS 背景和精灵图

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业2024.4.6学习笔记1 背景2 背景图片3 CSS 精灵图 作业 <!DOCTYPE html&…

消息中间件之消息通信模型MQ

一&#xff0c;为什么需要MQ&#xff1f; 应用中&#xff0c;经常需要对庞大的海量数据进行监控&#xff0c;随着网络技术和软件开发技术的不断提高&#xff0c;在实战开发中MQ的使用与日俱增&#xff0c;特别是RabbitMQ在分布式系统中存储转发消息&#xff0c;可以保证数据不…

ezuikit.js播放链接三种方式

第一种&#xff1a;iframe嵌入的方式 适用于ezopen开头的链接格式 举例&#xff1a;ezopen://open.ys7.com/BB98332770/1.hd.live <iframeid"ysOpenDevice"src{https://open.ys7.com/ezopen/h5/iframe? url${item.url}&autoplay1&accessToken${item…

全网最详细的网络安全自学笔记

1.选择方向 首先是选择方向的问题&#xff0c;网络安全是一个很宽泛的专业&#xff0c;包含的方向特别多。比如 web安全&#xff0c;系统安全&#xff0c;无线安全&#xff0c;二进制安全&#xff0c;运维安全&#xff0c;渗透测试&#xff0c;软件安全&#xff0c;IOT安全&am…

揭秘月赚600万的团购新模式:零风险购物竟能带来丰厚收益?

你是否曾经被看似赔钱的买卖吸引&#xff0c;最后却发现其背后的巨大盈利潜力&#xff1f;这种震撼的体验&#xff0c;让我深感好奇与惊喜。今天&#xff0c;我将与你分享一个不同寻常的商业模式&#xff0c;它或许能启发你走上属于自己的盈利之路。 这家小程序商城以其独特的团…

编译原理实验3(基于算符优先文法分析的语法分析器 )

实验目的 加深对语法分析器工作过程的理解&#xff1b;加强对算符优先分析实现语法分析程序的掌握&#xff1b;能够产用一种编程语言实现简单的语法分析程序&#xff1b;能够使用自己编写的分析程序对简单的程序段进行语法分析。 实验要求 根据简单表达式文法构造算符优先分…

实景三维在文化旅游领域的应用

实景三维技术&#xff0c;作为一种前沿的科技手段&#xff0c;近年来在文化旅游领域的应用逐渐崭露头角。它能够将真实世界的场景以三维的形式精确呈现&#xff0c;为游客带来身临其境的体验&#xff0c;为文化旅游注入新的活力。本文将探讨实景三维在文化旅游领域的应用及其所…

算法汇总啊

一些常用算法汇总 算法思想-----数据结构动态规划(DP)0.题目特点1.【重点】经典例题(简单一维dp&#xff09;1.斐波那契数列2.矩形覆盖3.跳台阶4.变态跳台阶 2.我的日常练习汇总(DP)1.蓝桥真题-----路径 算法思想-----数据结构 数据结构的存储方式 : 顺序存储(数组) , 链式存储…

【一步一步学】新手如何学习RouterOS

最近有很多同学私下问&#xff1a;ROS太难学&#xff0c;很难入门。 我在这里统一回答大家这个问题&#xff0c;其实入门还是比较简单&#xff0c;今天我写一个大概的学习过程 &#xff0c;后续是需要你们自己针对性学习与深入研究。 1. 了解RouterOS基础 学习任何东西&#x…

K8S之Job和CronJob控制器

这里写目录标题 Job概念适用场景使用案例 CronJob概念适用场景使用案例 Job 概念 Job控制器用于管理Pod对象运行一次性任务&#xff0c;例如&#xff1a;对数据库备份&#xff0c;可以直接在k8s上启动一个mysqldump备份程序&#xff0c;也可以启动一个pod&#xff0c;这个pod…

PostgreSQL入门到实战-第二弹

PostgreSQL入门到实战 PostgreSQL安装之Windows官网地址PostgreSQL概述Windows上安装PostgreSQL更新计划 PostgreSQL安装之Windows 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://www.postgresql.org/PostgreSQL概…

【Attention(0)】卷首语,从“SEAttention注意力效果秒杀CBAM”聊到“Transformer”

Attention 注意力是一个非常有价值的机制&#xff0c;例如我们耳熟能详的 SE attention。我们常常看到这样的标题《YOLOv8&#xff0c;注意力&#xff0c; SEAttention注意力&#xff0c;效果秒杀CBAM》。 其实&#xff0c;CBAM 是一种“卷积神经网络注意力模块”(Convolution…