首页 > 编程语言 >如何控制java虚拟线程的并发度?

如何控制java虚拟线程的并发度?

时间:2024-11-18 21:00:14浏览次数:1  
标签:10 java watch submitted 并发 线程 CompletableFuture order

jdk 21中的虚拟线程已经推出好一段时间了,确实很轻量,先来一段示例:

假如有一段提交订单的业务代码:

1     public void submitOrder(Integer orderId) {
2         sleep(1000);
3         System.out.println("order:" + orderId + " is submitted");
4     }
View Code

这里我们用sleep来模拟,每提交1个订单,大致耗时1秒。

如果有10个订单一起下单,顺序执行的话,至少10秒,很容易想到用多线程:

 1     @Test
 2     public void submitOrder1() {
 3         ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("submitOrder-pool-%d").build();
 4         ExecutorService submitOrderPool = new ThreadPoolExecutor(4, 16, 300L, TimeUnit.SECONDS,
 5                 new LinkedBlockingQueue<>(128), threadFactory, new ThreadPoolExecutor.DiscardOldestPolicy());
 6         CompletableFuture<Void>[] futures = new CompletableFuture[10];
 7         StopWatch watch = new StopWatch();
 8         watch.start();
 9         //下10个订单
10         for (int i = 0; i < 10; i++) {
11             final int orderId = i;
12             CompletableFuture<Void> future = CompletableFuture.runAsync(() -> submitOrder(orderId), submitOrderPool);
13             futures[i] = future;
14         }
15         CompletableFuture.allOf(futures).join();
16         watch.stop();
17         System.out.println("Time: " + watch.getTime());
18     }
View Code

这里我们使用了传统的线程池,核心线程数是4,小于10,所以会内部排队,最终执行效果大致如下:

order:0 is submitted
order:3 is submitted
order:1 is submitted
order:2 is submitted
order:4 is submitted
order:6 is submitted
order:7 is submitted
order:5 is submitted
order:8 is submitted
order:9 is submitted
Time: 3035
View Code

明显快多了,但是占用了4个传统的java线程。

 

我们改用虚拟线程来改写:

 1     @Test
 2     public void submitOrder2() {
 3         CompletableFuture<Void>[] futures = new CompletableFuture[10];
 4         StopWatch watch = new StopWatch();
 5         watch.start();
 6         //下10个订单(这里使用虚拟线程)
 7         try (ExecutorService service = Executors.newVirtualThreadPerTaskExecutor()) {
 8             for (int i = 0; i < 10; i++) {
 9                 final int orderId = i;
10                 CompletableFuture<Void> future = CompletableFuture.runAsync(() -> submitOrder(orderId), service);
11                 futures[i] = future;
12             }
13             CompletableFuture.allOf(futures).join();
14         }
15         watch.stop();
16         System.out.println("Time: " + watch.getTime());
17     }
View Code

运行效果:

 1 order:1 is submitted
 2 order:3 is submitted
 3 order:2 is submitted
 4 order:4 is submitted
 5 order:8 is submitted
 6 order:9 is submitted
 7 order:0 is submitted
 8 order:5 is submitted
 9 order:7 is submitted
10 order:6 is submitted
11 Time: 1035
View Code

对原有代码仅做了轻微改动,就能享受到虚拟线程的好处,占用资源更小,整体耗时更低,看上很完美!但真的这么丝滑吗?

 

这里有一个坑:正所谓“成也萧何,败也萧何”,虚拟线程这种轻量性的机制,导致它创建起来成本太低了,完全没有池化的必要,1台机器轻轻松松就可以瞬间创建上万甚至上百成的虚拟线程。相比传统的线程池机制(有coreSize,maxSize,workQueue缓冲,以及各种policy策略兜底),虚拟线程完全没有并发度控制的概念,如果瞬间生成大量的虚拟线程,每个里都是执行db/redis操作,很容易就把db、redis连接池打爆!!!

参考文档:
https://blog.moyucoding.com/jvm/2023/09/23/ultimate-guide-to-java-virtual-thread

https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html#GUID-DC4306FC-D6C1-4BCC-AECE-48C32C1A8DAA

标签:10,java,watch,submitted,并发,线程,CompletableFuture,order
From: https://www.cnblogs.com/yjmyzz/p/18553598

相关文章

  • JAVA反序列化学习-CommonsCollections1(基于ysoserial)
    准备环境JDK1.7(7u80)、commons-collections(3.x4.x均可这里使用3.2版本)JDK:https://repo.huaweicloud.com/java/jdk/7u80-b15/jdk-7u80-windows-x64.execc3.2:<dependency><groupId>commons-collections</groupId><artifactId>commons-collection......
  • Java多线程回顾总结
    目录一.线程与创建线程方式简介二.Thread继承三.实现Runnable接口四.Callable接口五.使用线程池一.线程与创建线程方式简介线程与进程的区别:1、一个进程至少包含一个线程2、比如电脑上QQ,运行起来就是一个进程,QQ可以聊天同时也可以传文件,聊天和传文件就是两个不同......
  • [Java] 获取操作系统类型
    需求描述在进行Java开发时,我们有时需要根据不同的操作系统执行不同的操作,例如在Windows系统下执行不同的命令,或者在Linux系统下调用不同的库函数。因此,判断当前运行的操作系统是十分重要的。此文将介绍如何使用Java判断当前操作系统,并给出相应的代码示例。代码示例OsUt......
  • ssm140基于java的奶茶店管理系统的设计与实现+jsp(论文+源码)_kaic
    毕业设计(论文)奶茶店管理系统 学   院                       专   业                       班   级                       学   号                   ......
  • 线程初见与线程管理
    Chap1,2HelloConcurrency与线程管理参考书目:《C++Concurrencyinaction》-ByAnthonyWillians,SecondEdition读书笔记Contents定义并发,多线程使用并发,多线程简单的C++多线程1.1什么是并发1.1.1计算机并发多核心:真正并行单核心:时间片切换。1.1.2并发方式......
  • JavaScript 字符串的常用方法有哪些
    速览JavaScript字符串的常用方法包括charAt、charCodeAt、concat、indexOf、lastIndexOf、slice、substring、toLowerCase、toUpperCase、trim、replace、split、padStart、padEnd等。详答1.基本信息JavaScript中的字符串是一种原始数据类型,提供了丰富的操作方法来处......
  • 【JAVA】Java基础—面向对象编程:类的其他特性—静态成员与方法
    在Java中,静态成员和静态方法是类的一部分,而不是类的实例的一部分。这意味着静态成员和方法可以在没有创建类的实例的情况下访问。理解静态成员和方法的概念对于Java开发至关重要,因为它们在内存管理、性能优化和设计模式中扮演着重要角色。理论知识1.静态成员静态变量:也称......
  • 【JAVA】Java基础—面向对象编程:类的其他特性—static 关键字的使用
    在Java编程中,static关键字是一个非常重要的概念,它用于定义类级别的成员,而不是实例级别的成员。理解static的使用对于编写高效、清晰和可维护的代码至关重要。在实际开发中,static关键字通常用于创建工具类、常量、单例模式以及共享数据等场景。理论知识1.static变量静态变......
  • Java基础知识(一)
    文章目录基础概念1.Java语言的特点2.JavaSEvsJavaEE3.JVMvsJDKvsJRE的区别a.JVMb.JDKc.JDEd.JDK、JRE和JVM的关系4.字节码5.Java语言“编译与解释并存”的特性6.AOT编译模式优势缺陷7.OracleJDKvsOpenJDK8.Java和C++的区别相同点:不同点......
  • Java学习之读取Yaml文件
    1.yaml文件示例:england:initialUrl:https://www.leisu.com/data/zuqiu/comp-82finalUrl:https://www.dszuqiu.com/league/35filePath:fileName:"英超.xlsx"spain:initialUrl:https://www.leisu.com/data/zuqiu/comp-120finalUrl:https://www.dszuqiu.......