2016-12-19 58 views
3

我一直在閱讀Play Framework documentation,發現這個報價混亂:非阻塞API如何工作?

注意,你可能會受到誘惑,因此包裝你阻止代碼 期貨。這並不會導致它阻塞,它只是意味着阻塞會發生在另一個線程中。您仍然需要使 確定您正在使用的線程池具有足夠的線程來處理阻塞。

我下的印象,所有這些非阻塞庫在自己的線程池做阻塞操作,並返回Future對象,這樣客戶端代碼將不會被阻塞。

但是這個引用說它不會使它成爲非阻塞的。我錯過了什麼嗎?有沒有非阻塞庫的先進魔術?

+0

阻擋不是「死鎖」提供。資源將從自己的角度被鎖定,但UI或任何主線程正在做的事情不會等待它解鎖。但資源*將在訪問時被鎖定。例如,訪問相同資源的第二個線程比完成第一個線程需要更長的時間,因爲它必須等待第一個線程解鎖資源。或者根據型號自行解鎖資源。 – Sebas

+0

期貨或承諾的全部目的是平滑資源的獲取和使用。它沒有提出一種替代的鎖定機制。 – Sebas

+0

異步和非阻塞有區別。我希望這個鏈接可以幫助你理解這兩者之間的區別:http://www.programmr.com/blogs/difference-between-asynchronous-and-non-blocking – Nagaraddi

回答

4

阻斷(如在阻塞IO)在IO的意義上意味着,發起IO線程進入睡眠狀態,直到IO結果是可用的。

非阻塞IO(或異步IO)告訴相關驅動程序(內核,一個DB驅動器等)來初始化一個IO動作,然後線程不斷做其他的東西。根據您使用的技術,您可以在回調(例如Node.js),通道(Java),期貨(C++),承諾(更新版本的Node.js)中處理異步IO結果(可能甚至是異常),任務(.Net),協程(C++ 17)等。

異步IO不使用線程使IO異步。這是這裏的關鍵。向線程池拋出一個阻塞IO動作不會使它異步,它只是在另一個線程上阻塞,而且非常不可伸縮。它將使線程池從線程中排除,因爲它們會隨着越來越多的阻塞IO提交而被阻塞。因爲他們自己的文件中寫道:

最常見的地方是典型的播放應用程序將被阻塞是 當它與一個數據庫。不幸的是,沒有一個主要 數據庫提供的JVM

異步數據庫驅動程序這意味着大多數數據庫執行的根本沒有爲Java提供異步IO - 拋出一個SQL查詢到一個線程池將會使thread-池線程塊。這就是他們的意思說:

注意,你可能會受到誘惑,因此包裝你的阻塞代碼 期貨。這並不會導致它阻塞,它只是意味着阻塞會發生在另一個線程中。

正如我們之前所說的,異步IO 不是在另一個線程上阻塞IO。

異步IO在Java中的一個例子是由標準包java.nio

+0

非阻塞IO的一個很好的例子是任何地方您正等待硬件在完成時通知您。例如。一個將數據塊發送到硬盤驅動器的驅動程序,然後立即將控制權返回給應用程序,以便它可以執行其他操作,然後在寫入完成時通知應用程序,或者提供其他一些機制來輪詢完成。 –

+0

謝謝你這麼好的解釋! –

+0

@DavidHaim請看看相關的問題:http://stackoverflow.com/questions/41241983/spring-jersey-async-controller-advantages –