最新要闻
- ppt应该保存什么格式
- 每日播报!高中最特别的时刻!高考前最后一个晚自习还记得多少?
- 哪吒CEO张勇:哪吒S是最漂亮的B级车 还是100万内最好的轿跑 热门
- 迪士尼一边涨价一边裁员:门票卖到799元
- 女子酒驾被查 喝了几瓶菠萝啤 以为是饮料 天天新资讯
- 天天热头条丨《小美人鱼》反派人类公主凡妮莎剧照出炉:比美人鱼颜值高、超甜
- ST华铁(000976)6月5日主力资金净买入651.43万元 全球热闻
- 西部矿业: 目前上半年尚未结束,公司暂时没有收到锂资源公司分红的消息_每日快讯
- 今日黄金td行情分析(2023年6月5日)
- 前沿资讯!净化器原厂/第三方滤芯对比:差距高下立判
- 网传北京将出台摩托车新规 京A禁止过户 多方回应
- 《暗黑4》玩家希望新角色继承地图数据:重新跑图太无聊 实时焦点
- 芯片投入决心绝不动摇!小米自研芯片公司玄戒增资至19.2亿 全球通讯
- 大众电动车高速收费站撞车爆燃致四人死亡 现场视频曝光:毫无减速_当前快看
- 每日看点!Java SPI概念、实现原理、优缺点、应用场景、使用步骤、实战SPI案例
- 世界短讯!让人欣慰?老外呼吁热门IP都应改为黑人:受社会尊重 改变低人一等形象
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
Java虚拟线程
清醒点
目录- Java虚拟线程
- 简介
- 线程(Thread)简介
- 并行(parallel)与并发(concurrent)执行
- 为什么要使用多线程?
- 多线程如何影响系统的效率?
- 对于唯一词计算效率又该如何呢?
- 增加线程是否可以解决这个问题呢?
- 线程内部是怎样工作的?
- Java内部线程实现模式
- 当前Java线程模型有什么问题吗?
- 现实世界的例子
- 虚拟线程(Virtual Thread)
- 虚拟线程如何工作
- Java虚拟线程实例
- 绿色线程 VS 虚拟线程
- 总结
- 参考
Java虚拟线程
flowchart LRintroduction-->a(why thread)-->b(parallel and concurrent execution)-->c(why threads?)-->d(how does thread work)-->e(java thread model)-->f(virtual thread)-->g(why virtual thread)-->h(comparasion)a-->cd-->f翻译自 screencapture-pradeesh-kumar-medium-an-era-of-virtual-threads-java
(资料图片仅供参考)
简介
“虚拟线程”的概念越来越火,很多编程语言都尝试将其加入到线程库中,Java也不例外。JDK19中便加入了虚拟线程(预览版)JEP425。本文主要深入浅出介绍线程的前世今身,以及虚拟线程带来的全新体验和优势,最后会对几种不同的线程实现方式进行对比
线程(Thread)简介
一个电脑程序,本质上就是实现特定任务任务的一系列指令。当你加载一个程序时,操作系统加载程序文件,并将其放置在一个指定区域(地址空间),然后执行它所包含的指令。这时候,它就被作为了一个“进程”。换句话说,一个进程就是一个程序运行在电脑中的实例。
一个线程就是进程里的一系列可以独立运行的指令,通常线程在CPU的一个核上运行。一个进程可以拥有多个线程,允许多个线程同时执行即同时执行多个任务,这样可以更好的利用CPU资源,提高任务吞吐量。例如,当你加载谷歌浏览器,系统便创建了一个谷歌浏览器的进程。你可以同事做很多事情,比如说同时下载文件和浏览网页,因为这些功能运行在不同的线程之上。线程也可以叫做轻量级进程,因为线程之间共享了进程的地址空间。
flowchart LRdisk--load-->memory--assign-->processprocess--include-->thread1process--include-->thread2process--include-->thread3process--include-->thread4并行(parallel)与并发(concurrent)执行
并行执行:同时执行多个任务。例如,一台四核的机器,可以每个核执行一个任务。所有的任务是同时执行的。
并发执行::电脑制造了一种同时执行任务数比CPU核数更多的错觉。例如,一个四核的电脑,可以执行8个不同的任务。因为你只有四核,所以必须做上下文切换来执行8个任务。在这里操作系统制造了一种并行执行8个任务的错觉。然而,实际上只有四个任务可以并行执行,因为只有四核。
并行执行图例:
flowchart LRcore1-->thread1core2-->thread2core3-->thread3core4-->thread4并发执行图例:
flowchart LRcore1-->a1(thread1)-->a2(thread4)-->a3(thread1)-->a4(thread8)-->a5(thread4)core2-->b1(thread2)-->b2(thread7)-->b3(thread2)-->b4(thread7)-->b5(thread2)core3-->c1(thread3)-->c2(thread5)-->c3(thread10)-->c4(thread3)-->c5(thread5)core4-->d1(thread5)-->d2(thread9)-->d3(thread5)-->d4(thread11)-->d5(thread1)为什么要使用多线程?
首先,让我们研究一下线程是怎样提高我们的系统效率的。
假如你现在有一台四核的电脑,你要写一个两数之和的程序,同时要求必须执行在12个线程中。
代码如下:
public class SumOfNums { static void sum() { int a = 1; int b = 2; int sum = a + b; System.out.println(sum); } public static void main(String[] args) { for (int i = 0; i < 12; i++) { Thread t = new Thread(SumOfNums::sum); t.start(); } }}
那么有多少线程可以并行执行呢?是否12个线程都可以并行执行?我们创建了12个线程,是否意味着12个线程是同时开始执行的?答案是否定的。我们的CPU只有四核,意味着我们并行执行的线程数上线就是四核。每个线程都必须分配到一个指定的核去执行,通过上下文切换来完成12个线程的并发执行。
那么为什么一个应用会有数百个线程?有什么用处?为什么我们不创建恰好等于CPU核数的线程?让我们更深入的研究一下。
任务通常有两种类型:CPU密集型以及IO密集型。
CPU密集型:任务执行高度依赖CPU,例如算术,逻辑,关联关系等,这些任务都是CPU密集型;
IO密集型:任务执行高度依赖输入/输出操作,例如网络交互,读取/存储文件,这些任务都是IO密集型;
那么我们上面提到的sum
任务属于哪一种呢?我们创建并初始化了两个变量a
和b
,将他们求和并输出到命令行。从始至终都没有任何的IO操作,数值计算是一个CPU操作,将结果写到两一个文件就是一个IO操作了。
通常来说,一个任务会混合CPU和IO操作。例如读取一个文本文件,并计算出其中所有的不同的单词,然后将结果写入到另一个文本文件。在这种情况下,读取和写入文件是一个IO操作,计算不同的单词是一个CPU操作。
多线程如何影响系统的效率?
再思考一下上面的CPU密集型求和代码。我们使用了12个线程并发执行这段代码。CPU内部切换前后台线程,这样就可以用4个核心完成12个线程的任务。如果还没有完成一个任务的时候,CPU会切换到另一个线程。
12个线程真的会提升效率吗?并非如此。当前的情况下,这里浪费了很多时间在切换上下文上。对于CPU密集型任务,最好使用和核心数统统的并发线程数,以达到最高的效率。
对于唯一词计算效率又该如何呢?
考虑这样一种情况,需要读取20个文本文件。CPU在读取文件时处于空闲状态,因为文件读取发生在硬盘驱动器上。所以只有当文件上下文都获取到了之后,CPU才会开始计算然后将结果写入到另一个文件。再写入过程中,CPU始终处于空闲状态,等待硬盘驱动器。
也就是说,我们执行的是如下图所示的单线程操作。
flowchart LRa(CPU)--wait-->b(__________IO__________)--hook-->c(CPU calculation)--wait-->d(____________IO__________)--hook-->e(CPU)如上图所示,CPU在IO进行的时候都是空闲的。这导致了CPU的核心始终跑不满100%占用率。
现在,我们考虑一下当我们在4核心CPU上跑4个线程。如下图所示:
flowchart LRa1(CPU)--wait-->b1(__________IO__________)--hook-->c1(CPU calculation)--wait-->d1(____________IO__________)--hook-->e1(CPU)a2(CPU)--wait-->b2(__________IO__________)--hook-->c(CPU calculation)--wait-->d2(____________IO__________)--hook-->e2(CPU)a3(CPU)--wait-->b3(__________IO__________)--hook-->c3(CPU calculation)--wait-->d3(____________IO__________)--hook-->e3(CPU)a4(CPU)--wait-->b4(__________IO__________)--hook-->c4(CPU calculation)--wait-->d4(____________IO__________)--hook-->e4(CPU)每一个线程被赋予了一个指定的核以并发执行。结果就导致了四核出现了与上面单核一样占用率不满的问题,IO期间核心依然是空闲的。
增加线程是否可以解决这个问题呢?
然我们来看一下如果我们使用八个线程会怎样:
flowchart LRcore1-->a1(thread1)-->a2(thread2__)-->a3(_____thread1______)-->a4(__thread2__)-->a5(thread1)core2-->b1(thread3)-->b2(____thread4____)-->b3(thread3)-->b4(thread4)-->b5(thread2)core3-->c1(thread6)-->c2(thread5)-->c3(thread10)-->c4(thread3)-->c5(thread5)core4-->d1(thread5)-->d2(thread6)-->d3(thread5)-->d4(thread8)-->d5(thread1)首先来看第一个核core1
,当thread1
进行IO操作时,core1
此时是空闲的。然而,当存在多个未执行线程时,核心会切换到另一个线程开始执行,直到thread1
完成了IO操作。这种方式可以最大化利用资源,提升多线程时的表现。
所以,在我们的第一个求和任务中,我们使用了比核心更多的线程数量没有获得效率提升,是因为浪费了过多的资源在上下文切换上。但是这里,8个线程提高了执行效率。我们从中可以学到,选择线程的数量,取决于IO操作频率和时间占用。IO操作占比越高,就需要越多的线程来提高执行效率。
线程内部是怎样工作的?
在我们继续研究虚拟线程前,必须要知道线程有哪些分类,以及他们怎么工作。
通常,现在操作系统中有两种不同的线程:核心线程以及用户线程
1. 核心线程
通常也叫做系统线程。核心线程通常由操作系统内核来安排管理。每个内核中的线程线程有一个TCB(Thread Control Block),其中包括了线程的优先级,状态,以及其它配置信息。核心线程是重量级的,需要系统调用来创建,调度,以及同步。
2. 用户线程
用户线程一般使用用户线程库进行管理和调度,不需要操作系统内核的干涉。内核不能意识到用户线程的变化。每个用户线程代表了一个应用中不同的数据结构,包括线程的状态信息和配置信息。用户线程是轻量级的,创建和销毁比系统线程更快。但是,依然会收到一些明确的限制,例如不能够享受到多处理器或者多核的优秀性能。
简单讲,当一个进程启动时,会启动一个默认线程,执行应用入口的main
方法。随后,进程会创建自己需要的额外线程。用户线程是不能直接执行的,必须映射到一个制定的内核线程,然后通过内核线程执行执行。用户线程和内核线程的映射关系有以下三种:
- M:1:所有的用户线程对应到一个内核线程上,通过库调度器进行调度;
- 1:1:每个用户线程对应一个内核线程;
- M:M:所有的用户线程映射到了一个内核线程池;
Java内部线程实现模式
绿色线程(Green Thread):远古时期,Java使用绿色线程模式。这个模式下,多线程的调度和管理有JVM完成。绿色线程模式才作用M:1线程映射模型。这里就有一个问题,Java不能够规模化管理这种线程,也就无法充分发挥硬件性能。同样的实现绿色线程也是一件非常有挑战性的事情,因为它需要非常底层的支持才能够良好运行。随后java移除了绿色线程,转而使用本地线程。这使得Java的线程执行比绿色线程更慢。
本地线程(Native Thread):从Java1.2开始从绿色线程切换到了本地线程模式。在操作系统的帮助下,JVM得以控制本地线程。本地线程的执行效率很高,但是开启和关闭他们的资源消耗较大。这就是为什么我们现在要使用线程池。这个模型遵循着1:1线程映射,即一个Java线程映射到一个内核线程。当一个java线程被创建时,相应的一个对应的核心线程也会被创建,用来执行线程代码。自此之后,本地线程模型的做法就延续到了今天。
当前Java线程模型有什么问题吗?
上面的章节中中,我们知道Java已经使用了本地线程模式。让哦我们看看这个模式有什么问题:
- Java的线程库已经很老旧了;
- 只是对于本地线程的一个简单包装;
- 本地线程的创建和管理资源消耗较大;
- 本地线程需要保存他们的调用栈在内存中,大概2MB~20MB的预留空间。如果你有4GB内存,如果每个线程占用20MB内存,那么你就只能创建大概200个线程;
- 因为本地线程是一种系统资源,加载一个新的本地线程大概需要1毫秒;
- 上下文切换代价昂贵,需要一个到内核的系统调用;
- 上面这些强制性的限制会限制线程创建的数量,同时会导致性能下降和过度的内存消耗。因为我们不能创建更多的线程;
- 我们不能通过增加更多的线程来增应用规模,因为上下文切换和内存占用的代价高昂;
现实世界的例子
考虑一台16GB内存的网络服务器。对于每个服务请求,都分配一个不同的线程。我们假设每个线程需要20MB内存空间,那么这台机器可以支持800个线程。当前,后端的API一般使用REST/SOAP调用方式,例如数据库操作和API信息转发这些IO密集型操作。由此可见,后端服务的主要是IO密集型而不是CPU密集型。
接着假设一下,一个IO操作需要100毫秒,请求执行(IO密集型)需要100毫秒,以及返回结果也需要100毫秒。同时,当每秒有800个请求时,线程数得到了最大容量。
让我们来计算一下单个请求的CPU占用时间
CPU时间 = 请求准备时间 + 返回结果准备时间= 0.1ms + 0.1ms= 0.2ms
对于800个请求呢?
800个线程的请求时间= 800 * 0.2ms= 160ms
受限于我们的内存容量,我们只能创建800个请求,也就导致了我们CPU使用率并不高
PUC使用率=160ms / 1000ms= 16%
那么如何才能使CPU的利用率到达90%呢?
16% = 800个线程90% = X个线程X = 4500
但是我们当前因为内存的限制不能创建那么多的线程,除非我们能突破这个限制,拥有90G内存。
90G的内存是一个比较离谱的数字,所以说创建本地线程很明显不能充分利用硬件资源。
虚拟线程(Virtual Thread)
虚拟线程是一个Java线程的轻量级实现版本,最早于JDK19中出现,当前仍是预览状态,可以通过Jvm配置项开启。
虚拟线程是JVM项目loom的一部分
虚拟线程解决了传递和维护本地线程的瓶颈问题,同时可以用之编写高吞吐的并发应用,榨干硬件资源的潜力。
与本地线程不同,虚拟线程并不有操作系统控制,虚拟线程是一个有JVM管理的用户态线程。对比于本地线程的高资源占用,每个虚拟线程只需要几个字节的内存空间。这是的它更适合控制管理大量的用户访问,或者说处理IO密集型任务。
在创建虚拟线程的数量上几乎没有限制,甚至可以创建一百万个,因为虚拟线程并不需要来自内核的系统调用。
在虚拟线程如此轻量化的条件下,线程池不再成为必须品,只需要在需要的时候尽情创建虚拟线程就好。
虚拟线程和传统的本地线程操作完全兼容,例如本地线程变量,同步块,线程中断,等等。
虚拟线程如何工作
JVM管理着一个本地线程的线程池。一个虚拟线程想要进行CPU操作时,就把自己关联到一个池中本地线程的队列中。当虚拟线程中的CPU操作执行完毕后,JVM会自动解除关联并挂起该虚拟线程,同时切换到并执行另一个虚拟线程。这就是为什么我们可以创建很多的虚拟线程,并且他们是如此的轻量级。
JVM使用M:N来完成虚拟线程与本地线程的映射。
Java虚拟线程实例
- 在现存的线程使用新的
ofVirtual()
工厂方法:
for (int i = 0; i < 5; i++) { Thread vThread = Thread.ofVirtual().start(() -> System.out.println("Hellow World!!!"));}
- 使用新的
Executors
工厂的newVirtualThreadExecutor()
方法:
public static void main(String[] args) throws InterruptedException { var executor = Executors.newVirtualThreadPerTaskExecutor(); for (int i = 0; i < 16; i++) { executor.submit(()-> System.out.println("Hello World!!!")); } executor.awaitTermination(1, TimeUnit.SECONDS); System.out.println("Finished");}
绿色线程 VS 虚拟线程
线程类型 | 简介 | 映射 |
---|---|---|
绿色线程 | 在一个系统线程上运行多个绿色线程 | M:1 |
平台线程(Java当前使用) | 系统线程的包装 | 1:1 |
虚拟线程 | 在多个系统线程中运行多个虚拟线程 | M:N(M>N) |
总结
总而言之,虚拟线程的新特性先对于传统多线程拥有很多优势。通过在用户空间提供的轻量化并发模型,虚拟线程使得编写并发程序更容易,使得大规模的线程并发成为可能。
参考
[1] screencapture-pradeesh-kumar-medium-an-era-of-virtual-threads-java
关键词:
-
环球速讯:【解决方法】loopback口添加同目的网段的地址后,无法用默认路由ping通该网段地址
环境:>工具:锐捷EVE,VMwareWorkstationPro远程工具:SecureCRT系统
来源: Java虚拟线程
9千多少儿百科全书百科知识ACCESS\EXCEL数据库|天天看热讯
环球速讯:【解决方法】loopback口添加同目的网段的地址后,无法用默认路由ping通该网段地址
ppt应该保存什么格式
【环球财经】日经股指涨破32000点 为1990年7月以来首次
每日播报!高中最特别的时刻!高考前最后一个晚自习还记得多少?
哪吒CEO张勇:哪吒S是最漂亮的B级车 还是100万内最好的轿跑 热门
迪士尼一边涨价一边裁员:门票卖到799元
女子酒驾被查 喝了几瓶菠萝啤 以为是饮料 天天新资讯
天天热头条丨《小美人鱼》反派人类公主凡妮莎剧照出炉:比美人鱼颜值高、超甜
ST华铁(000976)6月5日主力资金净买入651.43万元 全球热闻
ChatGLM-6B int4的本地部署与初步测试
Ambient Mesh:Istio 数据面新模式
某OA 11.10 未授权任意文件上传
判断非String对象是否为null,小伙竟然用StringUtils.isEmpty(obj+"")
全球负收益率债券规模反弹至近2万亿美元
西部矿业: 目前上半年尚未结束,公司暂时没有收到锂资源公司分红的消息_每日快讯
今日黄金td行情分析(2023年6月5日)
前沿资讯!净化器原厂/第三方滤芯对比:差距高下立判
网传北京将出台摩托车新规 京A禁止过户 多方回应
《暗黑4》玩家希望新角色继承地图数据:重新跑图太无聊 实时焦点
芯片投入决心绝不动摇!小米自研芯片公司玄戒增资至19.2亿 全球通讯
大众电动车高速收费站撞车爆燃致四人死亡 现场视频曝光:毫无减速_当前快看
MySQL的数据目录(Linux)
数据万象 | AIGC 存储内容安全解决方案
每日看点!Java SPI概念、实现原理、优缺点、应用场景、使用步骤、实战SPI案例
世界短讯!让人欣慰?老外呼吁热门IP都应改为黑人:受社会尊重 改变低人一等形象
视焦点讯!杭州一居民家门口地面有80℃ 热到烫脚:挖2小时后找到原因 网友称好险
.NET使用System.Speech轻松读取文本
环球快报:2023年最新辽宁省直住房公积金缴费基数是多少
新款Mac Pro现身跑分平台:M2 Ultra处理器 频率3.68 GHz
1.4kg重量就做到900ANSI流明!哈趣H2投影仪评测:旅行能用充电宝供电|每日报道
关注:不如隔壁New Bing:谷歌搜索AI功能被吐槽反应太慢
当前速讯:2023高考即将来临 应该怎么吃?专家科普:避免5个忌讳
50年前美国登月真的造假吗?日本将第三次挑战登月 证实可能性
苹果(AAPL.US)本周将举办开发者大会 首款头显终将亮相 环球快播报
2023陕西省大学生信息安全竞赛web writeup
世界速看:MySQL字符集与校对集规则说明
Linux环境安装JDK-焦点精选
取代手机不是吹!Win11原生运行安卓APP体验大升级:便捷丝滑-全球资讯
全球快看点丨乘客雨中候车 高铁站台为什么不能打伞上热搜:官方说明
两位国人男子放弃登顶珠峰花1万美元救人 获救女子只愿承担4成救援费 天天新消息
小鹏G6官宣神秘代言人:网友纷纷猜是林志颖! 环球资讯
世界今日讯!全脂/低脂可选:特仑苏纯牛奶2.7元/盒发车(商超6元)
两元人民币图片 两元人民币_每日速讯
今日美股市场行情快报(2023年6月5日)
《计算机网络》——华为基本配置命令_焦点热讯
700多心理测试性格测试大全ACCESS数据库 每日讯息
天天热资讯!帮你梳理了一份前端知识架构图
天天速读:亚马逊网络服务教程_编程入门自学教程_菜鸟教程-免费教程分享
今日热闻!hw面试常见中间件漏洞
特斯拉超充站充电 吃完饭下来“罚款”500!车主:这辈子不再买它了 当前热闻
XGP故障、键鼠无响应:Win11更新又出大量问题|天天快看
全球观点:明天出坞!我国首艘国产大型邮轮“爱达·魔都”内部实拍:可容纳5246人
经典重现!梁家辉把玩马自达CX-50行也车模 网友:别坐、堵车 世界百事通
微动态丨大众全新入门级轿车 朗逸XR即将上市!代替桑塔纳 或售5-7万
要闻速递:港股开盘 | 恒指高开0.34% 科网股表现分化 机构:三大因素支撑港股反弹
世界视点!SpringBoot打包成WAR包的时候把第三方jar包打到LIB文件夹下和把第三方jar包打入到SpringBoot jar包中
首批网红明星AI克隆人上线,花30元可与知名网红视频聊天
行驶中方向盘可能会掉 特斯拉召回部分Model Y!中国车主不受影响 前沿资讯
环球百事通!微软Office 365 AI定价曝光:年费10万美元 已有100家客户
反向带货 长安汽车4S直播间上演“尾翼夹手”:女销售惨叫不已_全球热文
宝骏悦也后装增程版方案出炉:4L油箱多跑80km、售价2000元-全球热推荐
人才!顾客打印身份证后怕泄露隐私 顺手把老板电脑系统重装了
6月5日最新秘鲁鱼粉外盘价格
AVX512惹麻烦 英特尔大小核给AMD上了一课 Zen5锐龙吸取教训
苹果首款头显明天发布!郭明錤泼冷水:类ChatGPT更重要
日本车的又一个基本盘:要崩了 天天看热讯
世界快报:全球首架载人“飞碟”在深圳起飞:水陆两栖起降 最快50km/h
变阵!热火总决赛G2首发:乐福顶替马丁出任首发!
每日动态!Blazor 使用代码直接在新窗口打开链接, 获取窗口宽度, 使用cookie
如何在Linux上启用 Nginx 的 HTTP/2 协议支持-聚看点
【读财报】公募REITs透视:建信、中金基金年内回撤逾15% 华安、博时基金等启动首批扩募
关于开通招商智星稳健配置混合型基金中基金(FOF-LOF)A类份额跨系统转托管业务的公告_环球时讯
国产大飞机C919商业首飞圆满成功:国产化率60% 年产能将达50架|全球通讯
顺利交付!神十五航天员带回了20多公斤实验样品:竟有一种虫子_最资讯
10年前的显卡都流畅 《暗黑4》被曝移植苹果平台:iPad也能玩_环球快报
还说4G成熟够用?中国网速全面秒美国 邬贺铨:总用户数激增 向5.5G发展
全球快资讯:读改变未来的九大算法笔记04_公钥加密
孩子严重烫伤9天才被家长送医 听偏方治疗:据给孩子手术 网友无语
SSD硬盘暴跌 你仍然需要一块机械硬盘:存数据更安全-世界短讯
实时:河南一村庄修路挖出大石龟?官方通报:上世纪修路埋的
柘汪中学:青少年科技教育成果丰硕
【DNS】域名服务 Bind实现
ASP.NET Core MVC 从入门到精通之自动映射(二)-独家焦点
实时焦点:不是我说 iPhone拍照怎么就像富士相机了?
世界热推荐:NVIDIA黄仁勋:我们从未忘记游戏玩家!
号称使用AI独立管理基金的私募改口了:AI并非主要用于交易 热点
人间第一情歌词完整版原唱_人间第一情歌词|全球看热讯
实时焦点:今金贷最新退付消息:2023年兑付最新声明退付通知(退付进展告知)
曝华为版ChatGPT将下月发布 名为“盘古Chat”-当前独家
每日热议!128秒回顾中国载人航天高燃时刻:杨利伟 居功至伟!
【环球报资讯】假鸡翅怎么做法?
Web安全-渗透测试-基础知识02
Web安全-渗透测试-基础知识01-环球视点
撼迅AMD显卡抹错硅脂 温度高达110℃!曝生产线自证清白
MPV无敌手 比亚迪赵长江:腾势D9月销将达1.5万-每日看点
专访:美国没有资格充当民主人权教师爷——访俄政治学家米尔扎扬-世界热消息
可提速400公里!成渝中线高铁两大隧道同时进洞
天涯老用户自救 结果一地鸡毛:情怀 是最不值钱的东西