日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Java 實現協程的方法

瀏覽:111日期:2022-08-22 18:28:32

協程(Coroutine)這個詞其實有很多叫法,比如有的人喜歡稱為纖程(Fiber),或者綠色線程(GreenThread)。其實究其本質,對于協程最直觀的解釋是線程的線程。雖然讀上去有點拗口,但本質上就是這樣。

協程的核心在于調度那塊由他來負責解決,遇到阻塞操作,立刻放棄掉,并且記錄當前棧上的數據,阻塞完后立刻再找一個線程恢復棧并把阻塞的結果放到這個線程上去跑,這樣看上去好像跟寫同步代碼沒有任何差別,這整個流程可以稱為coroutine,而跑在由coroutine負責調度的線程稱為Fiber。

java協程的實現

早期,在JVM上實現協程一般會使用kilim,不過這個工具已經很久不更新了,現在常用的工具是Quasar,而本文章會全部基于Quasar來介紹。

下面嘗試通過Quasar來實現類似于go語言的coroutine以及channel。

為了能有明確的對比,這里先用go語言實現一個對于10以內自然數分別求平方的例子。

func counter(out chan<- int) { for x := 0; x < 10; x++ { out <- x } close(out)}func squarer(out chan<- int, in <-chan int) { for v := range in { out <- v * v } close(out)}func printer(in <-chan int) { for v := range in { fmt.Println(v) }}func main() { //定義兩個int類型的channel naturals := make(chan int) squares := make(chan int) //產生兩個Fiber,用go關鍵字 go counter(naturals) go squarer(squares, naturals) //獲取計算結果 printer(squares)}

上面這個例子,通過channel兩解耦兩邊的數據共享。對于這個channel,大家可以理解為Java里的SynchronousQueue。下面我直接上Quasar版JAVA代碼的,幾乎可以原封不動的復制go語言的代碼。

public class Example { private static void printer(Channel<Integer> in) throws SuspendExecution, InterruptedException { Integer v; while ((v = in.receive()) != null) { System.out.println(v); } } public static void main(String[] args) throws ExecutionException, InterruptedException, SuspendExecution { //定義兩個Channel Channel<Integer> naturals = Channels.newChannel(-1); Channel<Integer> squares = Channels.newChannel(-1); //運行兩個Fiber實現. new Fiber(() -> { for (int i = 0; i < 10; i++) naturals.send(i); naturals.close(); }).start(); new Fiber(() -> { Integer v; while ((v = naturals.receive()) != null) squares.send(v * v); squares.close(); }).start(); printer(squares); }}

兩者對比,看上去Java似好像更復雜些,沒辦法這就是Java的風格,而且這還是通過第三方的庫來實現的。

說到這里各位肯定對Fiber很好奇了。也許你會表示懷疑Fiber是不是如上面所描述的那樣,下面我們嘗試用Quasar建立一百萬個Fiber,看看內存占用多少,我先嘗試了創建百萬個Thread。

for (int i = 0; i < 1_000_000; i++) { new Thread(() -> { try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } }).start();}

很不幸,直接報Exception in thread 'main' java.lang.OutOfMemoryError: unable to create new native thread,這是情理之中的。下面是通過Quasar建立百萬個Fiber。

public static void main(String[] args) throws ExecutionException, InterruptedException, SuspendExecution { int FiberNumber = 1_000_000; CountDownLatch latch = new CountDownLatch(1); AtomicInteger counter = new AtomicInteger(0); for (int i = 0; i < FiberNumber; i++) { new Fiber(() -> { counter.incrementAndGet(); if (counter.get() == FiberNumber) { System.out.println('done'); } Strand.sleep(1000000); }).start(); } latch.await();}

我這里加了latch,阻止程序跑完就關閉,Strand.sleep其實跟Thread.sleep一樣,只是這里針對的是Fiber。

最終控制臺是可以輸出done的,說明程序已經創建了百萬個Fiber,設置Sleep是為了讓Fiber一直運行,從而方便計算內存占用。官方宣稱一個空閑的Fiber大約占用400Byte,那這里應該是占用400MB堆內存,但是這里通過jmap -heap pid顯示大約占用了1000MB,也就是說一個Fiber占用1KB。

Quasar是怎么實現Fiber的

其實Quasar實現的coroutine的方式與Go語言很像,只不過前者是使用框架來實現,而go語言則是語言內置的功能。

不過如果你熟悉了Go語言的調度機制的話,那么對于Quasar的調度機制就會好理解很多了,因為兩者有很多相似之處。

Quasar里的Fiber其實是一個continuation,他可以被Quasar定義的scheduler調度,一個continuation記錄著運行實例的狀態,而且會被隨時中斷,并且也會隨后在他被中斷的地方恢復。

Quasar其實是通過修改bytecode來達到這個目的,所以運行Quasar程序的時候,你需要先通過java-agent在運行時修改你的代碼,當然也可以在編譯期間這么干。go語言的內置了自己的調度器,而Quasar則是默認使用ForkJoinPool這個具有work-stealing功能的線程池來當調度器。work-stealing非常重要,因為你不清楚哪個Fiber會先執行完,而work-stealing可以動態的從其他的等等隊列偷一個context過來,這樣可以最大化使用CPU資源。

那這里你會問了,Quasar怎么知道修改哪些字節碼呢,其實也很簡單,Quasar會通過java-agent在運行時掃描哪些方法是可以中斷的,同時會在方法被調用前和調度后的方法內插入一些continuation邏輯,如果你在方法上定義了@Suspendable注解,那Quasar會對調用該注解的方法做類似下面的事情。

這里假設你在方法f上定義了@Suspendable,同時去調用了有同樣注解的方法g,那么所有調用f的方法會插入一些字節碼,這些字節碼的邏輯就是記錄當前Fiber棧上的狀態,以便在未來可以動態的恢復。(Fiber類似線程也有自己的棧)。在suspendable方法鏈內Fiber的父類會調用Fiber.park,這樣會拋出SuspendExecution異常,從而來停止線程的運行,好讓Quasar的調度器執行調度。這里的SuspendExecution會被Fiber自己捕獲,業務層面上不應該捕獲到。如果Fiber被喚醒了(調度器層面會去調用Fiber.unpark),那么f會在被中斷的地方重新被調用(這里Fiber會知道自己在哪里被中斷),同時會把g的調用結果(g會return結果)插入到f的恢復點,這樣看上去就好像g的return是f的local variables了,從而避免了callback嵌套。

上面說了一大堆,其實簡單點來講就是,想辦法讓運行中的線程棧停下來,然后讓Quasar的調度器介入。

JVM線程中斷的條件有兩個:

1、拋異常

2、return。

而在Quasar中,一般就是通過拋異常的方式來達到的,所以你會看到上面的代碼會拋出SuspendExecution。但是如果你真捕獲到這個異常,那就說明有問題了,所以一般會這么寫。

@Suspendablepublic int f() { try { // do some stuff return g() * 2; } catch(SuspendExecution s) { //這里不應該捕獲到異常. throw new AssertionError(s); }}

以上就是Java 實現協程的方法的詳細內容,更多關于Java 實現協程的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
不卡av一区二区| 中文在线一区| 婷婷亚洲五月| 99精品网站| 婷婷激情久久| 亚洲国产一区二区在线观看| 欧美日韩尤物久久| 久久三级福利| 久久中文字幕av一区二区不卡| 最近高清中文在线字幕在线观看1| 国产欧美综合一区二区三区| 日韩精品免费视频人成| 亚洲精品第一| 青草国产精品| 免费亚洲婷婷| 欧美freesex黑人又粗又大| 欧美激情麻豆| 成人精品国产亚洲| 亚洲播播91| 久久国产福利| 国产日韩三级| 成年男女免费视频网站不卡| 日韩欧美国产精品综合嫩v| 久久精品国语| 日韩精品成人| 天堂av在线| 久久成人一区| 国产精品.xx视频.xxtv| 国产传媒av在线| 一区福利视频| 里番精品3d一二三区| 成人在线视频中文字幕| 亚洲一级影院| 国产伦理久久久久久妇女| 91欧美国产| 亚洲视频国产| 久久久男人天堂| 日韩精品视频网站| 久久久久午夜电影| 欧美亚洲tv| 国产精品婷婷| 日韩欧美字幕| 欧美在线日韩| 亚洲一区二区成人| 国产一区二区三区不卡av | 四虎国产精品免费观看| 激情综合婷婷| 亚洲精品日本| 亚洲一级特黄| 国际精品欧美精品| 日韩精品欧美大片| 亚洲欧美日韩在线观看a三区| 91亚洲国产| 国产视频一区二区在线播放| 亚洲午夜91| 国产96在线亚洲| 国产精品欧美三级在线观看 | 99国产精品免费视频观看| 国产精品亚洲欧美| 91亚洲无吗| 亚洲青青久久| 丝袜诱惑制服诱惑色一区在线观看| 久久电影tv| 欧美精品资源| 久久国产亚洲精品| 香蕉久久国产| 国产精品v日韩精品v欧美精品网站| 影视先锋久久| 在线人成日本视频| 吉吉日韩欧美| 国产精品成人自拍| 国产精品网站在线看| 久久精品超碰| 你懂的国产精品永久在线| 啪啪亚洲精品| 欧美经典一区| 精品视频一区二区三区在线观看 | 久久的色偷偷| 精品香蕉视频| 丁香六月综合| 一区在线观看| 视频精品一区| 青草av.久久免费一区| 亚洲精品福利| 美女视频黄 久久| 久久精品国内一区二区三区水蜜桃| 欧产日产国产精品视频| 麻豆亚洲精品| 国产黄色精品| 国产综合欧美| 69堂免费精品视频在线播放| 成人综合一区| 日韩影院在线观看| 欧美国产中文高清| 久久久国产精品一区二区中文| 亚洲美洲欧洲综合国产一区| 亚洲2区在线| 三上亚洲一区二区| 国产综合亚洲精品一区二| 欧美亚洲tv| 丝袜美腿亚洲色图| 国产精品专区免费| 国产精品一级在线观看| 午夜在线播放视频欧美| 裤袜国产欧美精品一区| 国产日韩一区二区三区在线播放| 久久亚洲专区| 精品国产中文字幕第一页| 蜜桃视频在线观看一区二区| 正在播放日韩精品| 国产欧美另类| 亚洲毛片网站| 久久国产精品99国产| 国产成人精品福利| 久久99久久人婷婷精品综合| 欧美1级日本1级| 黄色在线观看www| 伊人精品一区| 国产va免费精品观看精品视频| 欧美日韩第一| 亚洲性色视频| 国产一区三区在线播放| 西西人体一区二区| 在线精品亚洲欧美日韩国产| 久久午夜影院| 日韩精品中文字幕吗一区二区| 日韩欧美午夜| 久久精品国产免费| 免费在线观看日韩欧美| 欧美日韩日本国产亚洲在线 | 国产一区91| 日本不卡免费高清视频在线| 亚洲精品护士| 136国产福利精品导航网址| 日韩在线综合| 国产精品v一区二区三区| 亚洲免费观看高清完整版在线观| 99视频精品全国免费| 91日韩欧美| 国产欧美日韩在线观看视频| 国产精品一区亚洲| 不卡视频在线| 黄色成人精品网站| 女人天堂亚洲aⅴ在线观看| 精品美女久久| 国产精品久久久久9999高清| 国产亚洲欧美日韩在线观看一区二区| 国产高潮在线| 高清不卡亚洲| 国产伦久视频在线观看| 久久伊人久久| 欧美日韩色图| 亚洲精品97| 亚洲一级淫片| 青青国产91久久久久久| av资源中文在线天堂| 麻豆91小视频| av资源亚洲| 国产精品嫩草99av在线| 日本中文字幕不卡| 国产精品毛片久久| 九色porny丨国产首页在线| 久久蜜桃精品| 蜜桃传媒麻豆第一区在线观看| 午夜精品网站| 另类欧美日韩国产在线| 水蜜桃精品av一区二区| 久久久久观看| 午夜久久99| 国产亚洲人成a在线v网站| 欧美日韩在线播放视频| 欧美日韩四区| 国产日韩欧美一区二区三区 | 99国产精品99久久久久久粉嫩| 日本麻豆一区二区三区视频| 麻豆国产精品| aⅴ色国产欧美| 日本色综合中文字幕| 亚洲黄色在线| 久久久免费人体| 亚洲精品小说| 日韩不卡一区二区| 日韩精品一区二区三区免费观看| 久久福利精品| 国产资源在线观看入口av| 男人的天堂亚洲一区| 日韩av影院| 亚洲v天堂v手机在线| 国产精品v亚洲精品v日韩精品| 欧美天堂在线| 久久激情av| 日韩激情中文字幕| 欧美羞羞视频| 亚洲精品88| 欧美亚洲自偷自偷| 在线综合亚洲| 不卡视频在线| 国产高清亚洲| 日韩一区二区三区精品视频第3页| 久久激情中文|