专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

说一说Java19中的虚拟线程

  头条创作挑战赛
  Java19即将发布(2022年9月20日)。虽然Java19只是一个非LTS版本,但是其中的虚拟线程(VirtualThreads)和结构化并发(StructuredConcurrency)是两个让人非常期待的功能。虚拟线程在Java19虽然是预览功能,但是按照Java的发布周期,在下一个JavaLTS版本Java21中,虚拟线程就会成为正式功能。虚拟线程会为Java的并发编程带来颠覆性的影响。
  结构化并发在Java19是孵化功能。要成为正式功能还有很长的一段路要走。结构化并发会在另外的文章中介绍。
  当然了,我知道不少人看到虚拟线程之后,第一反应就是:这不就是协程吗?Go早就有了,Kotlin也早就有了;也会有人吐槽说,虚拟线程就这?怎么不支持ABC,也没有DEF?比XXX语言的差远啦,我还不如继续回去用XXX呢。
  其实不止是虚拟线程,Java之前的一些新特性,被人吐槽的也非常多。Java的泛型早就不知道被吐槽多少回了。Java9的模块系统,当初设想的前景很美好,但是直到现在,采用模块系统的第三方库和应用仍然非常之少。可以预期的是,虚拟线程肯定会让很多Java开发人员不满意。不过这是没办法的事情。作为一名Java程序员,这就是我们现在可以用的东西。如果它能让你的开发更简单,深入了解一下总没有坏处。
  吐槽结束,言归正传。使用Java线程时的常见问题
  作为一名Java程序员,在接触到多线程开发时,都会了解到这样一个重要的前提,那就是线程是稀缺资源。这个前提本身并没有什么问题,因为Java里面的线程封装了操作系统的线程,而线程由于其自身的开销较大,总体的数量是存在一个上限的。在这个前提之下,或者说限制之下,Java的多线程开发会有一些固有的模式:线程通常由线程池来管理。道理也很简单。线程是稀缺资源,创建的开销也大,就得复用。一个任务通常会在多个线程之间不断倒手。在高性能服务器端开发框架中,会有一个使用非阻塞IO的IO线程来接收请求。对于耗时较长的任务,这些请求会被转发给工作线程。处理完成之后再把结果通过IO线程来返回。
  由于这些固有模式,就引申出来一系列的问题,包括但不限于如下这些:Java线程池的创建和使用。在网上你可以搜索到与线程池相关的一大堆面试八股文。在多个线程之间使用threadlocal来传递上下文对象。对于一个请求,由于整个处理流程涉及多个线程池中的线程,追踪和调试变得非常困难。
  虚拟线程的出现,可以为解决这些问题提供新的思路。虚拟线程概述
  在Java19之前,Java只有一种类型的线程,Java19中称为平台线程(platformthread)。平台线程与操作系统的内核线程是一一对应的。与平台线程对应的就是新增的虚拟线程。
  虚拟线程是用户模式线程,由Java运行时进行调度,而不是由操作系统来调度。虚拟线程和内核线程是M对N的对应关系,也就是说,M个虚拟线程会被映射到N个内核线程上。
  平台线程和虚拟线程都使用java。lang。Thread来表示。这就意味为开发人员不需要学习新的API来使用虚拟线程。
  一个增加虚拟线程的重要动机是提供一种可扩展的方式来实现使用独占线程处理每个请求(threadperrequest)的并发风格。在编写服务端应用时,最自然的方式是对于每个请求,使用独占的线程来处理该请求,因为请求是相互独立的。这就是threadperrequest的并发风格。这种方式易于理解和编程实现,也易于调试和性能调优。
  然而,threadperrequest风格并不能简单地使用平台线程来实现。在实现上,平台线程是操作系统中线程的封装。操作系统的线程会占用资源,存在数量上限。对于一个要并发处理海量请求的服务器端应用来说,对每个请求都创建一个平台线程是不现实的。
  对于这个问题,很多框架都提供了解决方案。常用的思路是依赖非阻塞IO和异步编程。当某个请求在等待IO操作时,它会暂时让出线程,并在IO操作完成之后继续执行。通过这种方式,可以用少量的线程来同时处理大量的请求。这些框架可以提升系统的吞吐量,但是要求开发人员必须熟悉所使用的底层框架,并按照特定的风格来编写代码。
  在使用虚拟线程之后,开发人员可以使用最自然的方式来编写代码,把请求的处理逻辑全部在一个虚拟线程中完成。在完成对请求的处理之后,相应的线程也会被自动销毁。这极大地降低了编写高并发服务端应用的难度。
  虚拟线程是轻量级的,并不需要放入线程池中,在需要的时候创建即可。虚拟线程的调度
  虚拟线程由JDK负责调度。JDK把虚拟线程分配给平台线程,平台线程则由操作系统进行调度。
  一个虚拟线程所分配的平台线程被称为该虚拟线程的载体。在整个生命周期过程中,一个虚拟线程可能就会被调度到多个载体上。载体的标识对于虚拟线程是不可见的。
  JDK调度虚拟线程时,使用的是一个以FIFO模式工作的workstealingForkJoinPool。该ForkJoinPool的parallelism决定了调度时可以使用的平台线程的数量。该数量默认等于处理器的数量(通过Runtime。availableProcessors()获取),也可以通过系统属性jdk。virtualThreadScheduler。parallelism来设置。虚拟线程如何执行代码?
  在执行虚拟线程的代码时,JDK的线程调度器把虚拟线程分配到一个平台线程上执行。这个过程称为把虚拟线程绑定(mount)到平台线程。这个平台线程就成为了该虚拟线程的载体。在执行了某些代码之后,该虚拟线程可以从平台线程上解除绑定(unmount)。
  当虚拟线程在等待IO或是执行某些阻塞操作时,可以从平台线程上解除绑定。等阻塞操作完成之后,该虚拟线程可以被调度到新的平台线程上继续执行。虚拟线程的绑定和解除绑定操作,对于应用代码来说是透明的。
  有些JDK中的阻塞操作并不会解除对平台线程的绑定,因此会阻塞平台线程和底层的操作系统线程。这是由于操作系统或JDK自身的限制,比如很多文件操作以及Object。wait()方法调用都会产生这个效果。这些阻塞操作的实现会在内部对此进行补偿。具体的做法是临时增加JDK的调度器可以使用的线程数量。因此,JDK调度器的ForkJoinPool中的线程数量可能会超过parallelism指定的值。可以使用系统属性jdk。virtualThreadScheduler。maxPoolSize来指定调度器所允许的线程的最大值。
  在下面两种情况下,虚拟线程在执行阻塞操作时,会被锁定(pin)在载体上而无法解除绑定:在执行synchronized方法或块时,在执行native方法或外部方法时。
  虚拟线程的锁定可能会对应用的可伸缩性产生影响。当锁定发生时,调度器并不会对此进行补偿。为了避免经常出现的较长时间的锁定,可以考虑把synchronized方法或块替换成java。util。concurrent。locks。ReentrantLock。不过这种替换,应该建立在进行了充分性能测试的基础上。在大多数时候,锁定的影响并没有很大。虚拟线程代码展示
  介绍了这么多虚拟线程的内容之后,我们来看看到底如何在代码中使用虚拟线程。
  首先是如何创建虚拟线程。创建虚拟线程的第一种方式是使用Thread。ofVirtual()方法。在下面的代码中,一个新的虚拟线程被创建并启动。返回值thread是java。lang。Thread类型的对象。varthreadThread。ofVirtual()。name(myvirtualthread)。start(()System。out。println(运行中))
  第二种方式是使用Thread。startVirtualThread(Runnabletask)方法。这个方法等同于Thread。ofVirtual()。start(task)。
  第三种方式是使用ThreadFactory,如下面的代码所示。首先创建一个ThreadFactory,再使用ThreadFactory的newThread方法。varfactoryThread。ofVirtual()。factory();varthreadfactory。newThread(()System。out。println(在工厂中创建));
  另外一种更常用的方式是使用ExecutorService。ExecutorService可以为每个任务启动一个虚拟线程。这一类的ExecutorService对象可以使用Executors。newVirtualThreadPerTaskExecutor()或Executors。newThreadPerTaskExecutor(ThreadFactorythreadFactory)方法来创建。这一类的Executor对象所能创建的线程数量理论上没有上限(受限于内存)。
  在下面的代码中,创建了一个使用虚拟线程的ExecutorService对象,并向该ExecutorService提交了10000个任务。每个任务会休眠1秒钟。运行这段代码可以发现,所需要的执行时间很短,也不需要太多的资源。try(varexecutorExecutors。newVirtualThreadPerTaskExecutor()){IntStream。range(0,10000)。forEach(iexecutor。submit((){Thread。sleep(Duration。ofSeconds(1));returni;}));}
  最后展示一下JDK内部库对虚拟线程的支持。很多JDK内部库已经对虚拟线程提供了支持,主要是与HTTP和TCP相关的库,可以采用threadperrequest的模式。
  下面的代码使用JDK自带的HTTP服务器功能来实现一个返回当前时间的服务。HTTP服务器使用的Executor对象由Executors。newVirtualThreadPerTaskExecutor()方法创建,对每个请求使用虚拟线程来处理。importcom。sun。net。httpserver。HttpExchange;importcom。sun。net。httpserver。HttpHandler;importcom。sun。net。httpserver。HttpServer;importjava。io。IOException;importjava。net。InetSocketAddress;importjava。time。LocalDateTime;importjava。time。format。DateTimeFormatter;importjava。util。concurrent。Executors;publicclassSimpleHttpServer{publicstaticvoidmain(String〔〕args)throwsIOException{newSimpleHttpServer()。start();}publicvoidstart()throwsIOException{varserverHttpServer。create(newInetSocketAddress(8000),0);server。createContext(time,newTimeHandler());server。setExecutor(Executors。newThreadPerTaskExecutor(Thread。ofVirtual()。name(timeserver,1)。factory()));server。start();System。out。println(Timeserverstarted);}privatestaticclassTimeHandlerimplementsHttpHandler{Overridepublicvoidhandle(HttpExchangeexchange)throwsIOException{varresponseString。format(s,线程是s,LocalDateTime。now()。format(DateTimeFormatter。ISOLOCALDATETIME),Thread。currentThread()。getName());exchange。sendResponseHeaders(200,response。length());try(varoutexchange。getResponseBody()){out。write(response。getBytes());}}}}
  运行服务器之后,访问http:localhost:8000time时可以看到类似20220831T22:38:54。1251881,线程是timeserver4这样的返回结果。
  以上就是关于虚拟线程的基本内容,更多的内容会在后续的文章中介绍。

跟队记者尤文在布雷默争夺中已领先国米,明天将至关重要直播吧7月19日讯尤文跟队记者RomeoAgresti报道了都灵后卫布雷默的转会进程,他表示尤文在竞争中已经领先国米。该记者称,关于布雷默的竞争,尤文已经领先国米,明天将是非常重要兰世立先生给武汉大学的一封信,绝笔亲爱的母校我记得从我走进武大的那一天起,就有一句话一直激励着我,今天我以武大为荣,明天武大以我为荣!兰世立先生今年60岁多少年来我一直没有忘记,也从来不敢忘记。我很清楚,没有武大,男篮亚洲杯狂胜印度尼西亚50分进8强中国队和印度尼西亚比分108比58,狂赢50分,这场人员齐全,才是中国队的实力,希望再接再厉过关斩将,拿到最后的冠军,值得期待!!中国男篮加油,我们球迷是你们的后盾全场数据如下中国美好的一天从戴上一块好表开始什么是有文化气息的腕表?从卢浮宫的珍藏文物中,挑选出人类发展进程中历史性事件伟大人物艺术杰作文化图腾,将它们浓缩在一枚腕表中,这样的作品,就是有文化气息的腕表。即使这样的作品价格昂3年败光84亿后,中国特斯拉走向破产拜腾汽车,相比其他造车新势力起点更高,曾经的拜腾汽车要工厂有工厂,要产品有产品,江湖地位能够与蔚来小鹏威马并称造车新势力四小龙,但是最终却还是难免走向破产的境地。这家成立不过四年的具有400年历史的张小泉菜刀盲目与国际接轨的后果让人深思南有张小泉,北有王麻子。作为刀剪行业得领头羊,最近张小泉菜刀上了热搜,在网上引起了轩然大波。原因在于张小泉的菜刀拍蒜从中间断裂了。事情源于广州市民王女士用张小泉菜刀拍蒜,菜刀从中断4s店员工性侵未成年女生了吗?4s店的员工性侵女生了吗?文叶雨秋现在,这个问题已经不是问题了,警方通报称只是网恋交友问题,未发现涉事员工有违法犯罪问题,双方已达成和解。昨天一4s店员工被打的视频在网络热传,并迅网传4S店销售员是临时工?女孩是14岁初二学生?与事实有出入7月18日,据天津市公安局西青分局官方微博消息,针对互联网上出现中北镇一汽车4S店内销售人员被打视频。动图来自九派新闻经核查,该视频内容是2022年7月15日12时许,发生在西青区滥用职权罪的主体是哪些?滥用职权罪是指超越职权,违法决定处理其无权决定处理的事项,或者违反规定处理公务,致使公共财产国家和人民利益遭受重大损失的行为,那么民营企业的工作人员是滥用职权罪的主体吗?律师解答滥小镇做题家火了!却遭个别明星嘲讽题都做不完,还瞎操心这段时间以来,想必大家都被易烊千玺刷屏了。但这次他登上热搜,却不是因为参演了什么经典的电影或综艺节目,而是因为一场考试。2022年7月5日,国家话剧院招聘应届毕业生拟录用名单发布。美国通胀爆表,加息预期也炸了,但为何美股没有大跌?2022年7月13日,美国劳工部公布数据显示,6月CPI同比上涨9。1,远超市场预估的8。8,续创逾40年新高。在CPI数据公布后,美联储7月加息75个基点几乎是板上钉钉,100个
爆笑神评跟老板说馄饨里有虫子,老板对我翻白眼,还骂我不识货老板没虾阿。生死簿写的是ID。捂脸但凡打得过。准确的说,是带灯的体重秤。你好,方小姐。下次她会带人来驱魔。去看那个花红柳绿肥瘦肉也行。汤姆索亚历险记是吧。你这层可能犹太多了。我去这2022年,美国救护车上发生性丑闻,细扒整件事,恶意令人发指2018年4月,密西西比州格林县一位独居的孕妇突然感到身体不适。丈夫在外出差,家人也没陪伴在自己身边,即使她很慌,还是保持理智拨打了医疗急救电话。可她万万没想到,一切都毁在了这个求碎片商城更新一小时,88史诗皮肤无人问津,28勇者皮肤销量超高文丨可儿游戏说原创王者荣耀近期进行了一次版本更新,因为近期有七夕,所以此次版本更新的内容相对来说还是挺丰富的。更新了新品的皮肤,还上架了新款的个性按键个性表情击杀特效等等。多重新品47岁乐嘉晒近况,顶烈日跳绳皮肤黑到发亮,一身腱子肉似十八铜人饿了吗?戳右边关注我们,每天给您送上最新出炉的娱乐硬核大餐!8月4日七夕节这天,乐嘉在社交平台晒出了在国外度假的画面,顶烈日跳绳,一身腱子肉黑到发亮,状态抢眼引发热议。露面的乐嘉穿昆凌姐姐的偶像变成了妹夫昆凌大学毕业后,在周杰伦投资的服装店做兼职,所以认识这家店的股东,而这家店的股东又是周杰伦的同学机缘巧合之下两人就相识了。相识之后,周杰伦的妈妈也是很看好昆凌,认为昆凌尽管年纪不大谁在打嘴炮?之前是胡网红现在是佩洛西到底谁在打嘴炮?网红胡前总编还是佩洛西?现在看来佩洛西是在打嘴炮,虚晃一枪就走,代价要让台湾省承受。一网红总编前几天某时报的前主编打起了嘴炮,意思是说要军机伴飞专机,另外说要击落什秋后算账佩洛西先放话我要窜访台湾中国抗议!你来了就给你颜色看!佩洛西我如果不去,显得我怕你,美国的颜面又何在?顺利抵达,你能把我怎么地?中国舆论谴责!(够朋友的一起骂!)军演敲山震狗摸底为海贼王1056话完整大和正式加入草帽一伙,三大船长再次分道扬镳在此前的剧情中,刚刚海军大将绿牛入侵和之国,还和赤鞘九侠大和等人发生冲突,不过随后他就被红发香克斯的霸王色霸气吓退,灰溜溜地离开了和之国。而在漫画最新一话中,赤鞘九侠一行人已经回到看完值友们的定情信物,我又相信爱情了又到一年七夕,有人提前高呼孤寡,对恋爱的酸臭味表示抗议有人在这个佳节大撒狗粮,大方表露自己的爱意。在这个时代,爱情好像成了一种不可说摸不透的东西,当你谈起爱情时,你最先想到的是什么台媒解放军发射四款弹道导弹,全部飞越台湾,东风17首次上阵为反制美国众议院议长佩洛西窜访台湾,我军从昨天(4号)中午12点开始举行连续三天的大规模军事演习(台媒称为锁台军演)。从4号下午13时开始,我军先后进行了远程火箭炮和多款常规弹道导今天开始全国清查,实行覆盖性封群?谣言网传消息截图近日,网上热传覆盖性封群消息,引发网民的关注。消息称重要通知,从今天开始全国清查再二轮的实行覆盖性封群,这次行动从今天至8月18号晚8点。这次不但封群,群主号,连群员号
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网