【Java】虚拟线程与Java 8普通线程池的对比

news2024/10/1 1:19:20

文章目录

      • IO密集型任务
      • 高并发Web服务器
      • 异步编程
      • 微服务架构
      • 大规模并行处理
      • 事件驱动的应用
      • 不适用的场景
      • 使用对比
        • Java 8普通线程池
        • 虚拟线程
      • 性能分析
        • 资源消耗
        • 并发能力
        • 性能测试
      • 总结

在JDK 21之前,Java并发编程主要依赖于传统的线程池,如Java 8中的 Executors.newFixedThreadPool()

虚拟线程(Virtual Threads)是JDK 21引入的一种新型线程,它们旨在解决传统线程在轻量级并发任务处理中的局限性。以下是虚拟线程适用的场景:

IO密集型任务

虚拟线程特别适用于IO密集型任务,因为这些任务通常会花费大量时间等待外部资源,如网络响应、文件读写等。在等待期间,虚拟线程可以被挂起,而不占用操作系统线程资源,从而允许更多的虚拟线程在同一时间内运行。

高并发Web服务器

在Web服务器中,通常需要处理大量的并发请求,这些请求往往是IO密集型的。使用虚拟线程可以显著提高服务器的并发处理能力,因为它们能够以极低的成本创建数百万个线程。

异步编程

虚拟线程与Project Loom中的结构化并发(Structured Concurrency)相结合,为异步编程提供了更好的支持。这使得编写和维护异步代码更加容易。

微服务架构

在微服务架构中,服务之间通常会有大量的网络调用。虚拟线程可以用来处理这些网络调用,提高服务的响应速度和吞吐量。

大规模并行处理

当需要并行处理大量任务时,如大数据处理、分布式计算等,虚拟线程可以提供更高的并行度,因为它们不受物理线程数量的限制。

事件驱动的应用

事件驱动的应用,如消息队列消费者、事件流处理等,可以利用虚拟线程来处理大量的事件,而不需要为每个事件分配一个操作系统线程。

不适用的场景

虽然虚拟线程在许多场景下都非常有用,但以下场景可能不太适合使用虚拟线程:

  • CPU密集型任务:虚拟线程并不提供比传统线程更好的CPU利用率。对于CPU密集型任务,操作系统线程可能更合适,因为它们可以直接映射到CPU核心。
  • 需要精确线程控制的场景:如果应用程序需要精细控制线程的调度和行为,使用传统线程可能更为合适。
    总之,虚拟线程适用于那些需要大量并发、高吞吐量、且任务执行时间主要花费在等待外部资源响应的场景。在实际应用中,开发者应根据具体的应用需求和资源特性来决定是否使用虚拟线程。

使用对比

Java 8普通线程池

在Java 8中,创建一个固定大小的线程池并执行任务通常如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;
public class ThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个固定大小的线程池
        ExecutorService executor = Executors.newFixedThreadPool(10);
        // 使用IntStream并发处理10000个任务
        IntStream.range(0, 10000).forEach(i -> {
            executor.submit(() -> {
                System.out.println("处理任务:" + i);
                // 模拟任务执行时间
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        });
        // 关闭线程池
        executor.shutdown();
    }
}

在这个例子中,我们创建了一个固定大小为10的线程池。这意味着即使我们有10000个任务,同一时间也只有10个任务在执行。

虚拟线程

而使用虚拟线程的示例已经在之前的段落中给出。虚拟线程可以创建数百万个,而不受物理线程数量的限制。

性能分析

资源消耗
  • 普通线程池:每个线程都对应一个操作系统线程,创建和销毁线程的成本较高,且占用较多的内存和处理器资源。
  • 虚拟线程:虚拟线程是轻量级的,它们共享同一个或几个操作系统线程,因此创建和销毁的成本非常低,且占用的资源远少于普通线程。
并发能力
  • 普通线程池:由于操作系统线程资源的限制,线程池的大小通常受限,这限制了应用程序的并发能力。
  • 虚拟线程:由于虚拟线程的资源消耗非常低,可以创建大量的虚拟线程,从而实现更高的并发能力。
性能测试

以下是一个简单的性能测试,比较在处理大量任务时,普通线程池和虚拟线程的性能差异。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class PerformanceTest {
    public static void main(String[] args) throws InterruptedException {
        // 普通线程池性能测试
        long startTimePool = System.nanoTime();
        ExecutorService poolExecutor = Executors.newFixedThreadPool(100);
        IntStream.range(0, 1000000).forEach(i -> poolExecutor.submit(() -> {
            // 模拟任务执行
        }));
        poolExecutor.shutdown();
        poolExecutor.awaitTermination(1, TimeUnit.HOURS);
        long endTimePool = System.nanoTime();
        // 虚拟线程性能测试
        long startTimeVirtual = System.nanoTime();
        ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor();
        IntStream.range(0, 1000000).forEach(i -> virtualExecutor.submit(() -> {
            // 模拟任务执行
        }));
        virtualExecutor.shutdown();
        virtualExecutor.awaitTermination(1, TimeUnit.HOURS);
        long endTimeVirtual = System.nanoTime();
        // 输出结果
        System.out.println("普通线程池执行时间: " + TimeUnit.NANOSECONDS.toMillis(endTimePool - startTimePool) + " ms");
        System.out.println("虚拟线程执行时间: " + TimeUnit.NANOSECONDS.toMillis(endTimeVirtual - startTimeVirtual) + " ms");
    }
}

在这个测试中,我们分别用普通线程池和虚拟线程执行了100万个任务。虚拟线程通常会比普通线程池更快完成这些任务,因为它们创建和切换的成本更低。

总结

虚拟线程在处理大量并发任务时,相比Java 8普通线程池具有明显的性能优势。它们更加轻量级,可以创建更多数量的线程,从而提高应用程序的并发处理能力。然而,虚拟线程也并非万能,它们适用于IO密集型任务,而在CPU密集型任务中,传统线程可能仍然具有优势。在实际开发中,应根据具体场景选择合适的并发模型。

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

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

相关文章

大麦演唱会门票

切勿再令您所爱的人耗费高昂的价格去购置黄牛票 ⚠️核心内容参考: 据悉,于购票环节,大麦凭借恶意流量清洗技术,于网络层实时甄别并阻拦凭借自动化手段发起下单请求的流量,强化对刷票脚本、刷票软件以及虚拟设备的识别能力&#…

开源 AI 智能名片 2+1 链动模式 S2B2C 商城小程序的数据运营策略与价值创造

一、引言 1.1 研究背景 在当今数字化时代,数据运营已成为企业发展的核心驱动力。开源 AI 智能名片 21 链动模式 S2B2C 商城小程序作为一种创新的营销工具,与数据运营紧密相连。该小程序通过集成人工智能、大数据分析等先进技术,能够实时收集…

【问题解决】Xshell终端双击或者选中文字自动发送Ctrl+C

问题 在xshell终端,当鼠标双击或者选中一行文字时,xshell会自动发送一个 CtrlC 的命令。如下图: 原因 已知可能会导致这个问题的软件,关掉就没问题了: 有道词典金山词典词霸秒译bing翻译钉钉AI助理360极速搜索… …

Python保留数据删除Excel单元格的函数和公式

在分析处理Excel表格时,我们可能需要使用各种公式或函数对表格数据进行计算,从而分析出更多的信息。但在展示、分享或再利用分析结果时,我们可能需要将含有公式的单元格转换为静态数值,从而简化数据、保护计算结果不被更改&#x…

(c++)内存四区:1.代码区2.全局区(静态区)3.栈区4.堆区

//内存四区:1.代码区 2.全局区 3.栈区 4.堆区 1.放在代码区的有:1.写的代码:只读的、共享的、存放的二进制机器指令、由操作系统直接管理 2.放在全局区的有:1.全局的(变量或常量) 2.静态的&#xff0…

【毕业/转行】想从事GIS开发工程师?如何规划?

既然是GIS开发,那就离不开学习编程 那如何学习才能掌握呢?如何才能达到企业的用人标准? 给大家梳理了学习的路线,想从事gis开发的小伙伴可以直接按这个路线学习! 共分为6大阶段,让你从纯小白到成熟的三维GIS开发工程师! 大纲&#xff1a…

Python:import语句的使用(详细解析)(一)

相关阅读 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 import语句是Python中一个很重要的机制,允许在一个文件中访问另一个文件的函数、类、变量等,本文就将进行详细介绍。 在具体谈论import语句前&a…

linux驱动编程——等待队列

一、等待队列 可实现调用read函数时阻塞等。 1、流程 (1)初始化等待队列头(带参宏) init_waitqueue_head(q) 等待队列头wq数据类型: wait_queue_head_t,等待条件condition:int型变量。 &…

Actor 并发控制模型

目录 一、模型概述 二、模型特点 三、模型组成 四、模型优势 五、应用实例 一般来说,我们有两种策略来在并发线程中实现通信:共享内存和消息传递。大多数传统语言,并发线程之间的通信使用的都是共享内存,共享内存最大的问题就…

分糖果C++

题目&#xff1a; 样例解释&#xff1a; 样例1解释 拿 k20 块糖放入篮子里。 篮子里现在糖果数 20≥n7&#xff0c;因此所有小朋友获得一块糖&#xff1b; 篮子里现在糖果数变成 13≥n7&#xff0c;因此所有小朋友获得一块糖&#xff1b; 篮子里现在糖果数变成 6<n7&#xf…

为本地生活赛道从业者赋能,易播易赚开启“抖音直播分享会”

9月22日&#xff0c;由杭州易播易赚科技有限公司主办的“抖音直播分享会”在杭州市富阳区召开&#xff0c;此次会议吸引了来自全国各地的抖音直播从业者、有志于加入抖音直播事业的创业者以及行业内知名专家齐聚一堂&#xff0c;共同探讨行业发展趋势、分享实战经验&#xff0c…

tomcat版本升级导致的umask问题

文章目录 1、问题背景2、问题分析3、深入研究4、umask4.1、umask的工作原理4.2、umask的计算方式4.3、示例4.4、如何设置umask4.5、注意事项 1、问题背景 我们的java服务是打成war包放在tomcat容器里运行的&#xff0c;有一天我像往常一样去查看服务的日志文件&#xff0c;却提…

Mysql高级篇(中)——多版本并发控制 MVCC

多版本并发控制 MVCC 一、概述二、基本原理三、实现原理四、示例解释五、MVCC 优点六、现实中的实现七、MVCC 三剑客1. ReadView2. Undo Log3. Purge4. 三者之间的关系&#xff1a;5. 示例6. 总结 八、MVCC 整体操作流程⭐、readview1. 作用2. 工作机制3. 数据版本的可见性判断…

[云服务器15] 全网最全!手把手搭建discourse论坛,100%完成

首先&#xff0c;由我隆重地介绍Discourse&#xff1a; 这是一个优秀的论坛部署平台&#xff0c;相较于flarum Discuz!&#xff0c;有着更加简洁的画面、完全开源等优点&#xff0c;同时资源占用也不高&#xff01; 并且&#xff0c;这和我们亲爱的雨云论坛是有几分相似的哦&…

国庆偷偷卷!小众降维!POD-Transformer多变量回归预测(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现POD-Transformer多变量回归预测&#xff0c;本征正交分解数据降维融合Transformer多变量回归预测&#xff0c;使用SVD进行POD分解&#xff08;本征正交分解&#xff09;&#xff1b; 2.运行环境Matlab20…

Windows——解除Windows系统中文件名和目录路径的最大长度限制

第一步&#xff1a;打开本地组策略编辑器 按下Win R键打开运行窗口&#xff0c;输入 gpedit.msc 并回车&#xff0c;打开本地组策略编辑器。 第二步&#xff1a;开启 长路径设置 第三步&#xff1a;重启计算机

Windows环境Apache httpd 2.4 web服务器加载PHP8:Hello,world!

Windows环境Apache httpd 2.4 web服务器加载PHP8&#xff1a;Hello&#xff0c;world&#xff01; &#xff08;1&#xff09;首先需要安装apache httpd 2.4 web服务器&#xff1a; Windows安装启动apache httpd 2.4 web服务器-CSDN博客文章浏览阅读222次&#xff0c;点赞5次&…

Spark“数字人体”AI挑战赛_脊柱疾病智能诊断大赛_GPU赛道亚军比赛攻略_triple-Z团队

关联比赛: Spark“数字人体”AI挑战赛——脊柱疾病智能诊断大赛 triple-Z团队答题攻略 1 赛题分析 1.1 赛题回顾 本次比赛的任务是采用模型对核磁共振的脊柱图像进行智能检测。首先需要对5个椎体和6个椎间盘进行定位&#xff0c;这部分实际上就是11个关键点的检测任务&…

B2B商城交易解决方案:赋能企业有效重塑采购与销售新生态

在电商零售领域&#xff0c;商城系统始终是企业搭建商城的关键利器。 伴随着电商行业的蓬勃发展&#xff0c;各类新模式层出不穷&#xff0c;各种商城系统也应运而生&#xff0c;其中B2B商城更是最为常见的一种。 近年来&#xff0c;得益于电子商务的迅猛发展&#xff0c;B2B商…

C++入门基础知识92(实例)——实例17【实现一个简单的计算器】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于实现一个简单的计算器的相关内容&#x…