JDK19 - 虚拟线程如何进行业务代码的改造

news2024/11/24 8:42:43

JDK19 - 虚拟线程如何进行业务代码的改造

  • 一. 线程池的改造
  • 二. for 循环同步代码块改造
    • 2.1 自动关闭资源会等待所有异步任务执行完毕吗?

一. 线程池的改造

假设我们的代码中,原本是这样使用线程池的:

public static ExecutorService getThreadPoolExecutor(String threadName) {
    // 自定义线程名称
    ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(threadName).build();
    // 初始化线程池
    return new ThreadPoolExecutor(2,
            4,
            3,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(100),
            threadFactory,
            new ThreadPoolExecutor.AbortPolicy());
}

那么为了让业务代码更少的改动,我们就针对这类我们自己封装好的函数进行改造:

/**
 * 获取线程池,默认使用虚拟线程,不使用线程池
 *
 * @param threadName
 * @return
 */
public static ExecutorService getThreadPoolExecutor(String threadName) {
    return getThreadPoolExecutor(threadName, true);
}

public static ExecutorService getThreadPoolExecutor(String threadName, boolean isVirtualThread) {
    return getExecutorService(threadName, isVirtualThread, false);
}

/**
 - 获取线程池
 -  3. @param threadName      线程名称
 - @param isVirtualThread 是否虚拟线程
 - @param useThreadPool   是否使用线程池
 - @return 线程池
 */
private static ExecutorService getExecutorService(String threadName, boolean isVirtualThread, boolean useThreadPool) {
    ThreadFactory factory = isVirtualThread ? Thread.ofVirtual().name(threadName).factory()
            : Thread.ofPlatform().name(threadName).factory();
    // 如果使用线程池
    if (useThreadPool) {
        return new ThreadPoolExecutor(2,
                4,
                3,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(100),
                factory,
                new ThreadPoolExecutor.AbortPolicy());
    } else {
        // 否则不限制线程池大小
        return Executors.newThreadPerTaskExecutor(factory);
    }
}

那么我们只用改一处地方,外部甚至无感,我们就完成了虚拟线程池的代码改造了。另外还需要注意:

  • 如果改造虚拟线程,依旧使用虚拟线程池。若你的相关参数设置的很低。比如最大线程数。那么你的虚拟线程改造基本上是没啥意义的。
  • 使用虚拟线程,在确定好相关业务代码的QPS情况下,建议使用Executors.newThreadPerTaskExecutor()的方式来构建虚拟线程池。

二. for 循环同步代码块改造

我们依旧给一个案例代码:

@org.junit.Test
public void testForTest() {
    long start = System.currentTimeMillis();
    System.out.println("********************Start********************");
    for (int i = 0; i < 10; i++) {
        try {
            TimeUnit.SECONDS.sleep(2);
            System.out.println("hello");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    long finish = System.currentTimeMillis();
    System.out.println("********************finish********************");
    System.out.println(finish - start);
}

结果如下:

在这里插入图片描述
那么针对这类for循环执行同步代码块的,我们如何进行虚拟线程的改造?

首先我们可以利用try-with-resources语法块来完成,如下:

@org.junit.Test
public void testTryWithResource() {
    Instant start = Instant.now();
    System.out.println("********************Start********************");
    try (ExecutorService executorService = ThreadPoolExecutorService.getThreadPoolExecutor("test")) {
        for (int i = 0; i < 10; i++) {
            executorService.submit(() -> {
                try {
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println("hello");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
        }
    }
    Instant finish = Instant.now();
    System.out.println("********************finish********************");
    System.out.println(Duration.between(start, finish).toMillis());
}

结果如下:
在这里插入图片描述

来解释下啥意思:

  1. try-with-resources语法块时候Java 9中引入的一种新的try语法。可以更方便地管理资源的关闭,无需显式地编写finally块。
  2. 它针对的是一个实现了AutoCloseable接口的对象,它在try语句块执行完毕后会自动关闭。 try () {} 小括号里面的内容就是相关的资源,用var修饰。

很巧的是,我们的ExecutorService接口就实现了AutoCloseable接口,因此它可以被自动关闭。
在这里插入图片描述
AutoCloseable接口里面只定义了一个方法:clsoe()
在这里插入图片描述

2.1 自动关闭资源会等待所有异步任务执行完毕吗?

先说本文的案例,答案是可以的,因为从本文案例来看,虚拟线程的改造案例中,相关的信息输出都是在finish之前:
在这里插入图片描述
让我们再看一下ExecutorService里面对close方法的具体实现:如果发现线程池还没执行完毕,就会一直处于while循环当中。直到所有的异步任务执行完毕才会关闭线程池。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

套接字类型,地址族,数据序列

Socket: 1.套接字中使用的协议族 2.套接字数据传输类型信息 3.计算机间通信中所使用的协议信息 PF_INET协议族中, 符合SOCK_STREAM的只有一个: tcp 所以第三个参数为0 UDP同理 TCP套接字: 可靠的,按序传递的,基于字节的面向连接的数据传输方式的套接字 :tcp套接字数据不存在边…

前后端分离------后端创建笔记(10)用户修改

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

(二)结构型模式:4、组合模式(Composite Pattern)(C++实例)

目录 1、组合模式&#xff08;Composite Pattern&#xff09;含义 2、组合模式应用场景 3、组合模式的优缺点 4、组合模式的UML图学习 5、C实现组合模式的简单示例&#xff08;公司的OA系统&#xff09; 1、组合模式&#xff08;Composite Pattern&#xff09;含义 组合模…

短剧cps分销系统源码搭建 短剧cps系统开发 短剧项目怎么做

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、短剧是什么&#xff1f;二、短剧项目怎么做&#xff1f;三、总结 前言 短剧分销系统&#xff1a; 对接他人短剧小程序片源&#xff0c;仅推广分销。用户看…

Docker基础概述

目录 ​编辑 一、Docker简介 二、 Docker与虚拟机的区别 1.1namespace的六项隔离 二、Docker核心概念 2.1镜像 2.2容器 2.3仓库 三、安装Docker 3.1查看 docker 版本信息 四、Docker 镜像操作 4.1搜索镜像 4.2获取镜像 4.3镜像加速下载 4.4查看镜像信息 4.5根据…

FL Studio 2023年正式更新到发布21.1新版!功能介绍

很高兴地宣布在去年12月发布重大版本更新后&#xff0c;FL Studio在2023年8月正式更新到21.1版。本次更新虽然只是维护性质&#xff0c;但我们还是为大家带来了一些全新的功能&#xff0c;包括通过钢琴卷中的音阶捕捉和自定义音符工具&#xff0c;引入更快、更有创意的音符编辑…

救生艇(力扣)贪心 JAVA

给定数组 people 。people[i]表示第 i 个人的体重 &#xff0c;船的数量不限&#xff0c;每艘船可以承载的最大重量为 limit。 每艘船最多可同时载两人&#xff0c;但条件是这些人的重量之和最多为 limit。 返回 承载所有人所需的最小船数 。 示例 1&#xff1a; 输入&#xff…

ssm实验室耗材管理系统源码和论文

ssm实验室耗材管理系统源码和论文023 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让…

交叉编译基本概念

1 什么是交叉编译 1.1 本地编译 在解释什么是交叉编译之前&#xff0c;要先明白什么是本地编译。 本地编译可以理解为&#xff0c;在当前编译平台下&#xff0c;编译出来的程序只能放到当前的平台下运行&#xff0c;平时我们常见的软件开发都是属于本地编译。 比如我们在X8…

C++11并发与多线程笔记(2)

C11并发与多线程笔记&#xff08;2&#xff09; 线程启动、结束&#xff0c;创建线程多法、join&#xff0c;detach 1. 范例演示线程运行的开始1.1 创建一个线程&#xff1a;1.2 join1.3 datch1.4 joinable 2. 其他创建线程的方法2.1 用类 重载了函数调用运算符2.2 lambda表达式…

Visual Studio 2022连接远程系统进行C/C++开发

Visual Studio被称为是宇宙最强IDE&#xff0c;以前开发Linux C/C服务器程序&#xff0c;基本上都是在Windows上使用VS编写跨平台的C/C代码&#xff0c;然后先在VS中编译、链接、调试&#xff0c;然后在Linux下编译、链接&#xff0c;再针对Linux下的特定代码进行调试。后面Vis…

【日常积累】Linux之screen命令使用

使用场景 大家可能遇到这样的情况&#xff0c;当我们使用终端连接工具如xshell连接到一台服务器时&#xff0c;当执行一个花费时间比较长的命令时&#xff0c;如cp&#xff0c;scp或者其他时&#xff0c;当xshell由于某种原因突然断掉后在连上服务器时&#xff0c;之前执行的命…

我国农机自动驾驶系统需求日益增长,北斗系统赋能精准农业

中国现代农业的发展&#xff0c;离不开智能化、自动化设备&#xff0c;迫切需要自动驾驶系统与农用机械的密切结合。自动驾驶农机不仅能够缓解劳动力短缺问题&#xff0c;提升劳作生产效率&#xff0c;同时还能对农业进行智慧化升级&#xff0c;成为解决当下农业痛点的有效手段…

04 qt功能类、对话框类和文件操作

一 QT中时间和日期 时间 ---- QTime日期 ---- QDate对于Qt而言,在实际的开发过程中, 1)开发者可能知道所要使用的类 ---- >帮助手册 —>索引 -->直接输入类名进行查找 2)开发者可能不知道所要使用的类,只知道开发需求文档 ----> 帮助 手册,按下图操作: 1 …

docker私有仓库harbor

一、安装docker-compose yum install docker-compose -y 二、下载harbor安装包 tar -xf harbor-online-installer-v2.1.0.tgz cp harbor.yml.tmpl harbor.yml 三、修改harbor配置 [rootharbor ~]# vim harbor.ymlhostname: "修改为本机ip" harboradminpassword:…

vue 获取设备指纹

import Fingerprint2 from fingerprintjs2 // async 异步请求 async getFingerprint () {return new Promise((resolve, reject) > {Fingerprint2.getV18({}, (result, components) > {resolve(result)})})}, // 获取用户sessionasync getSession () {/* 等待获取设备指纹…

【c语言】动态内存管理(超详细)

他治愈了身边所有人&#xff0c;唯独没有治愈他自己—超脱 csdn上的朋友你们好呀&#xff01;&#xff01;今天给大家分享的是动态内存管理 &#x1f440;为什么存在动态内存分配 我们定义的局部变量在栈区创建 int n 4;//在栈上开辟4个字节大小int arr[10] { 0 };//在栈上开…

IT项目管理vs服务管理

如何通过IT项目管理来增强服务台运营呢&#xff1f; 我们知道许多人已经有了一个单独的项目管理工具来管理自己的 IT&#xff0c;并认为自己在服务台中不需要项目管理模块。首先&#xff0c;IT项目管理模块可能看起来与您设置中已有的常规工具没有什么不同&#xff0c;但肯定有…

2022年3月全国计算机等级考试真题(二级C语言)

2022年3月全国计算机等级考试真题&#xff08;二级C语言&#xff09; 第1题 下列有关栈论述正确的是&#xff08; &#xff09; A. 栈顶元素最先能被删除 B. 栈顶元素最后才被删除 C. 栈底元素永远不能被删除 D. 以上三种说法都不对 正确答案&#xff1a;A 得 0 / 1 分 第2题…

react-vite-antd环境下新建项目

vite 创建一个react项目 1. 安装vite并创建一个react项目1. 我使用的 yarn安装&#xff0c;基本配置项目名字, 框架react &#xff0c;js2. cd vite-react进入项目目录安装node包并启动项目 2. 安装引入Ant Design引入依赖&#xff08;我用的yarn&#xff0c;没有安装的也可以使…