精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Java不支持協程?那是你不知道Quasar!

開發 前端
本文介紹了Quasar框架的簡單使用,其具體的實現原理比較復雜,暫時就不在這里進行討論,后面打算單獨拎出來進行分析。

在編程語言的這個圈子里,各種語言之間的對比似乎就一直就沒有停過,像什么古早時期的"PHP是世界上最好的語言"就不提了,最近我在摸魚的時候,看到不少文章都在說"Golang性能吊打Java"。作為一個寫了好幾年java的javaer,這我怎么能忍?于是在網上看了一些對比golang和java的文章,其中戳中java痛點、也是golang被吹上天的一條,就是對多線程并發的支持了。先看一段描述:

Go從語言層面原生支持并發,并且使用簡單,Go語言中的并發基于輕量級線程Goroutine,創建成本很低,單個Go應用也可以充分利用CPU多核,編寫高并發服務端軟件簡單,執行性能好,很多情況下完全不需要考慮鎖機制以及由此帶來的各種問題。

看到這,我的心瞬間涼了大半截,真的是字字扎心。雖然說java里的JUC包已經幫我們封裝好了很多并發工具,但實際高并發的環境中我們還要考慮到各種鎖的使用,以及服務器性能瓶頸、限流熔斷等非常多方面的問題。

再說回go,前面提到的這個goroutine究竟是什么東西?其實,輕量級線程goroutine也可以被稱為協程,得益于go中的調度器以及GMP模型,go程序會智能地將goroutine中的任務合理地分配給每個 CPU。

好了,其實上面說的這一大段我也不懂,都是向寫go的哥們兒請教來的,總之就是go的并發性能非常優秀就是了。不過這都不是我們要說的重點,今天我們要討論的是如何在Java中使用協程。

協程是什么?

我們知道,線程在阻塞狀態和可運行狀態的切換,以及線程間的上下文切換都會造成性能的損耗。為了解決這些問題,引入協程coroutine這一概念,就像在一個進程中允許存在多個線程,在一個線程中,也可以存在多個協程。

那么,使用協程究竟有什么好處呢?

首先,執行效率高。線程的切換由操作系統內核執行,消耗資源較多。而協程由程序控制,在用戶態執行,不需要從用戶態切換到內核態,我們也可以理解為,協程是一種進程自身來調度任務的調度模式,因此協程間的切換開銷遠小于線程切換。

其次,節省資源。因為協程在本質上是通過分時復用了一個單線程,因此能夠節省一定的資源。

類似于線程的五種狀態切換,協程間也存在狀態的切換,下面這張圖展示了協程調度器內部任務的流轉。

綜合上面這些角度來看,和原生支持協程的go比起來,java在多線程并發上還真的是不堪一擊。但是,雖然在Java官方的jdk中不能直接使用協程,但是,有其他的開源框架借助動態修改字節碼的方式實現了協程,就比如我們接下來要學習的Quasar。

Quasar使用

Quasar是一個開源的Java協程框架,通過利用Java instrument技術對字節碼進行修改,使方法掛起前后可以保存和恢復jvm棧幀,方法內部已執行到的字節碼位置也通過增加狀態機的方式記錄,在下次恢復執行可直接跳轉至最新位置。

Quasar項目最后更新時間為2018年,版本停留在0.8.0,但是我在直接使用這個版本時報了一個錯誤:

這個錯誤的大意就是這個class文件是使用的高版本jdk編譯的,所以你在低版本的jdk上當然無法運行了。這里major版本號54對應的是jdk10,而我使用的是jdk8,無奈降級試了一下低版本,果然0.7.10可以使用:

<dependency>
<groupId>co.paralleluniverse</groupId>
<artifactId>quasar-core</artifactId>
<version>0.7.10</version>
</dependency>

在我們做好準備工作后,下面就寫幾個例子來感受一下協程的魅力吧。

1、運行時間

下面我們模擬一個簡單的場景,假設我們有一個任務,平均執行時間為1秒,分別測試一下使用線程和協程并發執行10000次需要消耗多少時間。

先通過線程進行調用,直接使用Executors線程池:

public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch=new CountDownLatch(10000);
long start = System.currentTimeMillis();
ExecutorService executor= Executors.newCachedThreadPool();
for (int i = 0; i < 10000; i++) {
executor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
});
}
countDownLatch.await();
long end = System.currentTimeMillis();
System.out.println("Thread use:"+(end-start)+" ms");
}

查看運行時間:

好了,下面我們再用Quasar中的協程跑一下和上面相同的流程。這里我們要使用的是Quasar中的Fiber,它可以被翻譯為協程或纖程,創建Fiber的類型主要可分為下面兩類:

public Fiber(String name, FiberScheduler scheduler, int stackSize, SuspendableRunnable target);
public Fiber(String name, FiberScheduler scheduler, int stackSize, SuspendableCallable<V> target);

在Fiber中可以運行無返回值的SuspendableRunnable或有返回值的SuspendableCallable,看這個名字也知道區別就是java中的Runnable和Callable的區別了。其余參數都可以省略,name為協程的名稱,scheduler是調度器,默認使用FiberForkJoinScheduler,stackSize指定用于保存fiber調用棧信息的stack大小。

在下面的代碼中,使用了Fiber.sleep()方法進行協程的休眠,和Thread.sleep()非常類似。

public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch=new CountDownLatch(10000);
long start = System.currentTimeMillis();

for (int i = 0; i < 10000; i++) {
new Fiber<>(new SuspendableRunnable(){
@Override
public Integer run() throws SuspendExecution, InterruptedException {
Fiber.sleep(1000);
countDownLatch.countDown();
}
}).start();
}

countDownLatch.await();
long end = System.currentTimeMillis();
System.out.println("Fiber use:"+(end-start)+" ms");
}

直接運行,報了一個警告:

QUASAR WARNING: Quasar Java Agent isn't running. If you're using another instrumentation method you can ignore this message; otherwise, please refer to the Getting Started section in the Quasar documentation.

還記得我們前面說過的Quasar生效的原理是基于Java instrument技術嗎,所以這里需要給它添加一個代理Agent。找到本地maven倉庫中已經下好的jar包,在VM options中添加參數:

-javaagent:E:\Apache\maven-repository\co\paralleluniverse\quasar-core\0.7.10\quasar-core-0.7.10.jar

這次運行時就沒有提示警告了,查看一下運行時間:

運行時間只有使用線程池時的一半多一點,確實能大大縮短程序的效率。

2、內存占用

在測試完運行時間后,我們再來測試一下運行內存占用的對比。通過下面代碼嘗試在本地啟動100萬個線程:

public static void main(String[] args) {
for (int i = 0; i < 1000000; i++) {
new Thread(() -> {
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}

本來以為會報OutOfMemoryError,但是沒想到的是我的電腦直接直接卡死了…而且不是一次,試了幾次都是以卡死只能重啟電腦而結束。好吧,我選擇放棄,那么下面再試試啟動100萬個Fiber協程。

public static void main(String[] args) throws Exception {
CountDownLatch countDownLatch=new CountDownLatch(10000);
for (int i = 0; i < 1000000; i++) {
int finalI = i;
new Fiber<>((SuspendableCallable<Integer>)()->{
Fiber.sleep(100000);
countDownLatch.countDown();
return finalI;
}).start();
}
countDownLatch.await();
System.out.println("end");
}

程序能夠正常執行結束,看樣子使用的內存真的比線程少很多。上面我故意使每個協程結束的時間拖得很長,這樣我們就可以在運行過程中使用Java VisualVM查看內存的占用情況了:

可以看到在使用Fiber的情況下只使用了1G多一點的內存,平均到100萬個協程上也就是說每個Fiber只占用了1Kb左右的內存空間,和Thread線程比起來真的是非常的輕量級。

從上面這張圖中我們也可以看到,運行了非常多的ForkJoinPool,它們又起到了什么作用呢?我們在前面說過,協程是由程序控制在用戶態進行切換,而Quasar中的調度器就使用了一個或多個ForkJoinPool來完成對Fiber的調度。

3、原理與應用

這里簡單介紹一下Quasar的原理,在編譯時框架會對代碼進行掃描,如果方法帶有@Suspendable注解,或拋出了SuspendExecution,或在配置文件META-INF/suspendables中指定該方法,那么Quasar就會修改生成的字節碼,在park掛起方法的前后,插入一些字節碼。

這些字節碼會記錄此時協程的執行狀態,例如相關的局部變量與操作數棧,然后通過拋出異常的方式將cpu的控制權從當前協程交回到控制器,此時控制器可以再調度另外一個協程運行,并通過之前插入的那些字節碼恢復當前協程的執行狀態,使程序能繼續正常執行。

回頭看一下前面例子中的SuspendableRunnable和SuspendableCallable,它們的run方法上都拋出了SuspendExecution,其實這并不是一個真正的異常,僅作為識別掛起方法的聲明,在實際運行中不會拋出。當我們創建了一個Fiber,并在其中調用了其他方法時,如果想要Quasar的調度器能夠介入,那么必須在使用時層層拋出這個異常或添加注解。

看一下簡單的代碼書寫的示例:

public void request(){
new Fiber<>(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
String content = sendRequest();
System.out.println(content);
}
}).start();
}

private String sendRequest() throws SuspendExecution {
return realSendRequest();
}

private String realSendRequest() throws SuspendExecution{
HttpResponse response = HttpRequest.get("http://127.0.0.1:6879/name").execute();
String content = response.body();
return content;
}

需要注意的是,如果在方法內部已經通過try/catch的方式捕獲了Exception,也應該再次手動拋出這個SuspendExecution異常。

總結

本文介紹了Quasar框架的簡單使用,其具體的實現原理比較復雜,暫時就不在這里進行討論,后面打算單獨拎出來進行分析。另外,目前已經有不少其他的框架中已經集成了Quasar,例如同樣是Parallel Universe下的Comsat項目,能夠提供了HTTP和DB訪問等功能。

雖然現在想要在Java中使用協程還只能使用這樣的第三方的框架,但是也不必灰心,在OpenJDK 16中已經加入了一個名為Project Loom的項目, 在OpenJDK Wiki上可以看到對它的介紹,它將使用Fiber輕量級用戶模式線程,從jvm層面對多線程技術進行徹底的改變,使用新的編程模型,使輕量級線程的并發也能夠適用于高吞吐量的業務場景。

責任編輯:姜華 來源: 碼農參上
相關推薦

2010-08-23 09:56:09

Java性能監控

2020-06-12 09:20:33

前端Blob字符串

2020-07-28 08:26:34

WebSocket瀏覽器

2009-12-10 09:37:43

2022-10-13 11:48:37

Web共享機制操作系統

2021-02-01 23:23:39

FiddlerCharlesWeb

2011-09-15 17:10:41

2016-07-22 17:55:07

云計算

2021-10-17 13:10:56

函數TypeScript泛型

2021-12-29 11:38:59

JS前端沙箱

2021-12-22 09:08:39

JSON.stringJavaScript字符串

2015-06-19 13:54:49

2020-08-11 11:20:49

Linux命令使用技巧

2012-11-23 10:57:44

Shell

2022-11-04 08:19:18

gRPC框架項目

2020-09-15 08:35:57

TypeScript JavaScript類型

2020-04-27 10:34:23

HTTPDNSDNS網絡協議

2017-01-19 15:11:37

AndroidRetrofitRxCache

2023-02-27 09:20:24

絕對定位CSS

2017-12-15 13:44:22

點贊
收藏

51CTO技術棧公眾號

日本免费一区二区三区视频观看| 91国产免费观看| 97碰碰视频| 午夜精品久久久久久久久久久久久蜜桃| 日本欧美韩国国产| 欧美四级电影网| 人妻无码一区二区三区四区| 伦理片一区二区三区| 极品尤物av久久免费看| 性欧美办公室18xxxxhd| 超薄肉色丝袜一二三| 亚洲小说春色综合另类电影| 欧美日韩中文字幕在线视频| 亚洲欧美日产图| 五月激情婷婷网| 激情综合亚洲精品| 2019中文字幕在线观看| 日本二区三区视频| 久草在线综合| 欧美一区二区三区的| 苍井空浴缸大战猛男120分钟| 操你啦在线视频| 国产婷婷色一区二区三区在线| 99一区二区三区| 亚洲永久精品一区| 国产专区一区| 欧美成aaa人片在线观看蜜臀| 成人性生交大免费看| 亚洲国产高清在线观看| 欧美色区777第一页| 国产精品无码一区二区在线| av网址在线播放| 国产精品美女www爽爽爽| 久久久久久高清| 亚洲成人久久精品| 国产一区二区美女诱惑| 国产精品人成电影在线观看| 久久久久久久久久久久久av| 精久久久久久| 欧美高清视频在线观看| 天天天天天天天天操| 日韩av在线中文字幕| 亚洲人成网在线播放| 日韩精品一区二区三区高清免费| 视频一区视频二区欧美| 91麻豆精品国产自产在线| 91在线视频观看免费| 日韩激情电影| 欧美日韩中文在线| 日韩免费视频播放| av不卡高清| 亚洲成人精品一区| 国产精品久久..4399| 久草在线资源站资源站| 一区二区三区四区中文字幕| 做爰高潮hd色即是空| 老司机在线永久免费观看| 国产精品无人区| 亚洲欧美日韩国产yyy| 香蕉视频在线看| 1000精品久久久久久久久| 亚洲欧洲日韩精品| 在线观看国产原创自拍视频| 中文字幕制服丝袜一区二区三区| 亚洲视频sss| 免费av不卡| 亚洲激情五月婷婷| 警花观音坐莲激情销魂小说| 成人看av片| 亚洲国产综合色| 91好吊色国产欧美日韩在线| 在线能看的av网址| 日本韩国欧美一区二区三区| 在线视频日韩一区 | 欧美高清在线视频观看不卡| 精品少妇theporn| 国产精品久久777777毛茸茸 | 蜜臀av.com| 国产蜜臀在线| 色综合天天综合狠狠| 亚洲成人av免费看| 国产人与zoxxxx另类91| 亚洲第一区在线观看| 少妇精品一区二区三区| 99久久婷婷国产综合精品电影√| 欧美精品午夜视频| 91蜜桃视频在线观看| 日韩**一区毛片| 亚洲一区二区三| 日韩精品一二| 亚洲视频在线观看三级| 久操网在线观看| 高清av一区二区三区| 欧美一级二级在线观看| 色综合久久五月| 久久在线视频| 97在线观看免费| 在线免费看毛片| 成人国产精品免费观看动漫| 日韩精品成人一区二区在线观看| 伊人福利在线| 色美美综合视频| 久久久久亚洲av片无码v| 校园春色另类视频| 另类视频在线观看| 天天操夜夜操视频| 国产河南妇女毛片精品久久久| 欧美不卡福利| 七七成人影院| 777久久久精品| 97超碰在线免费观看| 欧美福利影院| 国产精品视频自拍| 日韩黄色影片| 亚洲一区二区欧美| 日本不卡一区二区在线观看| 久操国产精品| 97人人做人人爱| a天堂中文在线观看| 久久精品男人的天堂| 日韩精品在线视频免费观看| 伊人久久大香伊蕉在人线观看热v 伊人久久大香线蕉综合影院首页 伊人久久大香 | 国产在线精品一区二区| 青青影院一区二区三区四区| 51精品视频| 日韩女优视频免费观看| 日本裸体美女视频| 日韩不卡在线观看日韩不卡视频| 精品国产一区二区三区免费| 手机在线免费看av| 欧美一区二区在线视频| 亚洲人做受高潮| 青青草原综合久久大伊人精品优势| 国产欧美日韩综合精品二区| a免费在线观看| 欧美日本韩国一区| 欧美成人久久久免费播放| 爽爽淫人综合网网站| 国产原创精品| 人在线成免费视频| 亚洲国模精品私拍| 久久精品欧美一区二区| 国产成人免费在线观看| 99视频精品全部免费看| 国产精品va视频| 美女视频黄免费的亚洲男人天堂| 一级全黄裸体免费视频| 国产精品久久久久久福利一牛影视 | 日韩久久久久久久久久久久久| 一级毛片久久久| 亚洲欧美国内爽妇网| 神马久久久久久久| 国产校园另类小说区| 男人的天堂日韩| 欧美日韩一二| 国产综合在线观看视频| 成人在线观看亚洲| 91麻豆精品国产91久久久资源速度 | 91深夜福利视频| 成人video亚洲精品| 日韩视频免费观看高清在线视频| 粉嫩av性色av蜜臀av网站| 国产精品一区二区在线观看不卡 | 成人sese在线| 免费av观看网址| 国产精品嫩草影院在线看| 国产精品人成电影在线观看| 免费av在线| 精品国产制服丝袜高跟| 国产情侣在线视频| 国产欧美日韩视频在线观看| 成年人在线看片| 我不卡手机影院| 99在线影院| 亚洲欧洲自拍| 久久精品成人一区二区三区| www.成人精品| 欧美小视频在线观看| 日日操免费视频| 国产成人av电影在线观看| 欧美色图另类小说| 久久精品国产99久久| 97人人干人人| 成人av免费电影网站| 日韩有码片在线观看| 懂色av一区二区三区四区| 黑人极品videos精品欧美裸| 国产又粗又猛又爽又黄的视频四季| 国产乱人伦偷精品视频免下载| 青青草精品视频在线| 成人写真视频| 国产精品久久国产精品| 99re66热这里只有精品4| 久久亚洲国产成人| 天天综合网天天综合| 欧美日韩成人高清| 日韩三级av在线| 亚洲三级电影网站| 日本丰满少妇裸体自慰| 国产尤物一区二区| 少妇性饥渴无码a区免费| 91成人看片| 欧美午夜精品理论片a级大开眼界| 国产美女亚洲精品7777| 国产成人一区二区三区电影| 色呦呦呦在线观看| 中文字幕亚洲在线| 国产精品国产高清国产| 欧美一级在线观看| 樱花视频在线免费观看| 亚洲福利一区二区| 国产高清视频免费在线观看| 久久久国产一区二区三区四区小说 | 中文一区二区在线观看| 久久精品女同亚洲女同13| 激情都市一区二区| 国产一级不卡毛片| 亚洲毛片一区| 在线观看17c| 天天做天天爱天天综合网| 欧美xxxx黑人又粗又长密月| 国产精品对白| 97超碰人人看人人 | 全部av―极品视觉盛宴亚洲| 青青草视频国产| 我不卡影院28| av动漫免费观看| 日韩a一区二区| 色爱区成人综合网| 国产精品视频一区二区三区四蜜臂| 国产精品毛片va一区二区三区| 95精品视频| 国产日韩av在线播放| 丰满少妇一区| 国产精品jizz在线观看麻豆| 成人免费影院| 日本欧美爱爱爱| 久久r热视频| 欧美在线观看一区二区三区| 91制片在线观看| 韩日精品中文字幕| 97人人爽人人澡人人精品| 色综合老司机第九色激情| 国产精品一区二区三区视频网站| 少妇激情综合网| 91社区在线观看| 日韩一区二区三区xxxx| 日本激情视频在线观看| 中文字幕精品久久久久| 99视频在线观看地址| 在线视频一区二区| 免费a级在线播放| 久久久精品国产网站| 国产精品扒开做爽爽爽的视频| xvideos成人免费中文版| 免费在线看黄色| 久久的精品视频| 污视频网站在线免费| 欧美情侣性视频| 国产在线xxx| 久久免费视频网| 亚洲午夜天堂| 国产精品一区专区欧美日韩| 99er精品视频| 国产精品乱码一区二区三区| 日韩有码中文字幕在线| 日韩av免费电影| 91精品1区| 国产欧美日韩小视频| 国产日韩综合| 日日噜噜噜噜久久久精品毛片| 久久er99热精品一区二区| 少妇愉情理伦片bd| 99视频精品免费视频| 熟女俱乐部一区二区视频在线| 中文字幕精品综合| 欧美xxxxx少妇| 亚洲成人a级片| 91色视频在线观看| 一区二区在线免费播放| 国产精品亚洲不卡a| 亚洲黄页网站| 一级日韩一区在线观看| 国产成人三级在线播放 | 国外成人在线直播| 北岛玲heyzo一区二区| 国产日韩精品视频| av毛片精品| 五月天色一区| 尤物在线精品| 成人性生交免费看| av高清久久久| 中文字幕资源站| 欧美日韩亚洲精品一区二区三区| 91福利在线观看视频| 日韩国产在线看| av大片在线| 国产精品第七十二页| av成人综合| 精品久久免费观看| 久久综合图片| www.美色吧.com| 国产精品成人网| 国产嫩bbwbbw高潮| 精品人在线二区三区| av免费观看一区二区| 7m第一福利500精品视频| 成人av在线播放| 色就是色欧美| 国产精品尤物| 亚洲欧美日韩偷拍| 亚洲欧美在线视频| 波多野结衣啪啪| 亚洲黄页视频免费观看| www红色一片_亚洲成a人片在线观看_| 欧美一区二区影院| 高清精品视频| 中文字幕色呦呦| 久久99久久99| 欧美黄色高清视频| 日韩欧美一区二区三区| 国产 日韩 欧美 综合| 久久亚洲影音av资源网| 伦一区二区三区中文字幕v亚洲| 玛丽玛丽电影原版免费观看1977| 激情综合激情| 国产51自产区| 亚洲综合丝袜美腿| 99久久国产免费| 久久手机免费视频| 欧美日韩卡一| 视频一区二区三| 三级久久三级久久久| 亚洲av片不卡无码久久| 欧美日韩国产一区二区三区| 韩国av在线免费观看| 色综合久久久久久中文网| 精品视频成人| 老司机午夜网站| 国产伦精品一区二区三区视频青涩 | 欧美日韩一区二区三区不卡| 国产福利在线| 国产精品劲爆视频| 成人3d精品动漫精品一二三| 狠狠操精品视频| 日本一区二区免费在线观看视频| 国产又大又黄又粗| 亚洲精品有码在线| 亚洲精品国产嫩草在线观看| 日本欧洲国产一区二区| 爽好多水快深点欧美视频| 国产一区二区三区四区五区六区| 在线观看一区不卡| av资源在线观看免费高清| 国产精品永久在线| 亚洲欧洲美洲一区二区三区| 爱情岛论坛亚洲自拍| 亚洲综合视频在线| 日韩一级免费视频| 青青草一区二区| 日韩欧美网址| 秋霞午夜鲁丝一区二区| 亚洲国产婷婷综合在线精品| 深爱激情五月婷婷| 国产精品福利网| 久久久久久久久久久9不雅视频| 午夜免费福利网站| 亚洲成a人片在线不卡一二三区| 男人av在线| 成人av资源在线播放| 欧美日韩久久| 国产精品1000部啪视频| 欧美在线观看一区| caoporn97在线视频| 99中文视频在线| 久久亚洲美女| 永久久久久久久| 日韩av一区在线| 国外成人福利视频| 18黄暴禁片在线观看| 国产日韩欧美激情| 99久久免费国产精精品| 91国语精品自产拍在线观看性色 | 久久国产激情视频| 亚洲在线观看免费视频| 欧美日韩免费做爰大片| 成人有码视频在线播放| 亚洲人妖在线| 99久久久无码国产精品不卡| 欧美xxxxxxxxx| 成人免费网站www网站高清| av在线免费观看国产| 国产日韩v精品一区二区| 国产高清视频免费| 欧洲日韩成人av| 欧美日韩18| 国产第一页精品| 亚洲另类图片色| 伊色综合久久之综合久久| 国产视频在线视频|