[英]Why is Vert.x called responsive even though it is single threaded
我從 Vert.x 文檔(以及其中的一些編碼)中了解到 Vert.x 是單線程的並在事件池中執行事件。 它不等待 I/O 或任何網絡操作,而不是給另一個事件時間(這在任何 Java 多線程框架中都沒有)。
但我無法理解以下內容:
我從 Vert.x 文檔(以及其中的一些編碼)中了解到 Vert.x 是單線程的並在事件池中執行事件。
它是事件驅動的,基於回調的。 它不是單線程的:
每個 Vertx 實例維護多個事件循環,而不是單個事件循環。 默認情況下,我們根據機器上可用內核的數量選擇數量,但這可以被覆蓋。
它不等待 I/O 或任何網絡操作
它使用非阻塞或異步 I/O,不清楚是哪一個。 Reactor 模式的使用表明非阻塞,但也可能不是。
而不是給另一個事件時間(這在任何 Java 多線程框架中都沒有)。
這是沒有意義的。
- 單線程如何比多線程好?
不是。
如果有數百萬個傳入的 HTTP 請求怎么辦? 會不會比其他多線程框架慢?
是的。
- Verticles 依賴於 CPU 內核。 擁有多少個 CPU 內核,就可以讓多個 Verticle 並行運行。 一種在虛擬機上運行的語言為什么可以根據需要使用 CPU? 據我所知,Java VM (JVM) 是一個僅使用另一個 OS 進程的應用程序(這里我對 OS 和 JVM 的理解較少,因此我的問題可能很幼稚)。
根據上面的引用,它使用每個內核一個線程,或者通過覆蓋它來選擇任何線程。
- 如果單線程非阻塞概念如此有效,那么為什么我們不能在多線程環境中使用相同的非阻塞概念呢?
你可以。
不會更快嗎?
是的。
還是說,是因為CPU一次只能執行一個線程?
一個多核 CPU 一次可以執行多個線程。 我不知道“是不是因為”中的“它”指的是什么。
首先,Vertx 無論如何都不是單線程的。 它只是不會產生更多它需要的線程。
其次,這與 Vertx 完全無關,JVM 將線程映射到本機操作系統線程。
第三,我們可以在多線程環境中擁有非阻塞行為。 它不是每個 CPU 一個線程,而是每個內核一個線程。
但接下來的問題是:“這些線程在做什么?”。 因為通常,為了有用,他們需要其他資源。 網絡、數據庫、文件系統、內存。 在這里它變得棘手。 當你是單線程時,你沒有競爭條件。 在任何時候訪問內存的唯一人就是你。 但是如果你是多線程的,你需要關心互斥鎖,或者任何其他保持數據一致的方式。
問:
單線程如何比多線程好? 如果有數百萬個傳入的 HTTP 請求怎么辦? 會不會比其他多線程框架慢?
答:
Vert.x 不是單線程框架,它確實確保您在應用程序中部署並注冊到 vert.x 的“verticle”主要是單線程的。
這樣做的原因是多線程的並發使具有鎖同步和其他需要多線程通信處理的概念的並發變得復雜。
雖然 Verticle 是單線程的,但確實使用了稱為事件循環的東西,這是這種范式背后的真正力量,在 Vert.x 的案例中稱為反應器模式或多反應器模式。 多個 Verticle 可以在一個應用程序中注冊,這些 Verticle 之間的通信通過一個事件總線運行,該事件總線使 Verticle 能夠在內部使用基於事件的傳輸協議,但這也可以使用其他一些技術進行分發以管理集群。
事件循環處理進入一個線程的事件,但一切都是異步的,因此計算由循環處理,當它完成時,信號通知可以使用結果。
因此,所有計算要么基於回調,要么使用諸如 Reactive.X/纖維/協程/通道之類的東西。
由於 Vert.x 的更簡單的並發通信模型和其他不錯的特性,它實際上比現有的許多阻塞和純多線程模型更快。 數字
問:
如果單線程非阻塞概念如此有效,那么為什么我們不能在多線程環境中使用相同的非阻塞概念呢? 不會更快嗎? 還是說,是因為CPU一次只能執行一個線程?
答:
就像第一個問題所說的那樣,它並不是真正的單線程。 實際上,當您知道某事正在阻塞時,您必須使用名為executeBlocking
的方法注冊計算,這將使其在由 Vert.x 管理的ExecutorService
上多線程運行
Vert.x 的模型大多更快的原因也在這里,因為事件循環更好地利用了 cpu 計算特性和約束。 這主要由 Netty 項目提供支持。
多線程和它的鎖和同步的開銷給它的多反應器模式超過 Vert.x 帶來了很大的壓力。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.