1. 程式人生 > >Java之阻塞和非阻塞以及同步和非同步的區別

Java之阻塞和非阻塞以及同步和非同步的區別

阻塞和非阻塞,同步和非同步

1 例子

故事:老王燒開水。

出場人物:老張,水壺兩把(普通水壺,簡稱水壺;會響的水壺,簡稱響水壺)。

老王想了想,有好幾種等待方式

1.老王用水壺煮水,並且站在那裡不管水開沒開,每隔一定時間看看水開了沒。-同步阻塞

老王想了想,這種方法不夠聰明。

2.老王還是用水壺煮水,不再傻傻的站在那裡看水開,跑去寢室上網但是還是會每隔一段時間過來看看水開了沒有,水沒有開就走人。-同步非阻塞

老王想了想,現在的方法聰明瞭些,但是還是不夠好。

3.老王這次使用高大上的響水壺來煮水,站在那裡但是不會再每隔一段時間去看水開,而是等水開了,水壺會自動的通知他。-非同步阻塞

老王想了想,不會呀,既然水壺可以通知我,那我為什麼還要傻傻的站在那裡等呢,嗯,得換個方法。

4.老王還是使用響水壺煮水,跑到客廳上網去,等著響水壺自己把水煮熟了以後通知他。-非同步非阻塞

老王豁然,這下感覺輕鬆了很多。

  • 同步和非同步

    同步就是燒開水,需要自己去輪詢(每隔一段時間去看看水開了沒),非同步就是水開了,然後水壺會通知你水已經開了,你可以回來處理這些開水了。
    同步和非同步是相對於操作結果來說,會不會等待結果返回。

  • 阻塞和非阻塞

    阻塞就是說在煮水的過程中,你不可以去幹其他的事情,非阻塞就是在同樣的情況下,可以同時去幹其他的事情。阻塞和非阻塞是相對於執行緒是否被阻塞。

其實,這兩者存在本質的區別,它們的修飾物件是不同的。阻塞和非阻塞是指程序訪問的資料如果尚未就緒,程序是否需要等待,簡單說這相當於函式內部的實現區別,也就是未就緒時是直接返回還是等待就緒。
而同步和非同步是指訪問資料的機制,同步一般指主動請求並等待I/O操作完畢的方式,當資料就緒後在讀寫的時候必須阻塞,非同步則指主動請求資料後便可以繼續處理其它任務,隨後等待I/O,操作完畢的通知,這可以使程序在資料讀寫時也不阻塞。

2 詳細介紹

網路IO的模型大致包括下面幾種

  • 同步模型(synchronous IO)
    • 阻塞IO(bloking IO)
    • 非阻塞IO(non-blocking IO)
    • 多路複用IO(multiplexing IO)
    • 訊號驅動式IO(signal-driven IO)
  • 非同步IO(asynchronous IO)
    • 非同步IO

網路IO的本質是socket的讀取,socket在linux系統被抽象為流,IO可以理解為對流的操作。對於一次IO訪問,資料會先被拷貝到作業系統核心的緩衝區中,然後才會從作業系統核心的緩衝區拷貝到應用程式的地址空間,所以一般會經歷兩個階段:

  1. 等待所有資料都準備好或者一直在等待資料,有資料的時候將資料拷貝到系統核心;
  2. 將核心快取中資料拷貝到使用者程序中;

對於socket流而言:

  1. 等待網路上的資料分組到達,然後被複制到核心的某個緩衝區;
  2. 把資料從核心緩衝區複製到應用程序緩衝區中;

2.1 阻塞IO

2.1.1 介紹

這也是最常用的模型,預設情況下所有的套接字都是 阻塞 的;

我們把recvfrom函式視為系統呼叫,因為我們正區分程序和核心,系統呼叫一般都會從在應用程序空間中執行切換到核心空間中執行,一段時間後又再切換回來;

我們可以從圖中看到,應用程序從 進行系統呼叫 到 複製資料報到應用程序的緩衝區完成 的整段時間內是被阻塞的;在這個過程中,要麼正確到達,要麼系統呼叫被訊號打斷;直到資料報被複制到使用者程序完成後,使用者程序才解除阻塞的狀態,當然,這是使用者程序自己進行的阻塞;

2.1.2 優點和缺點

  • 優點:能夠及時返回資料,無延遲;方便除錯;
  • 缺點:需要付出等待的代價;

2.2 非阻塞IO

2.2.1 介紹

非阻塞,當所請求的I/O操作非得把當前程序設定成睡眠才能完成時,不要把當前程序設定成睡眠,而是返回一個錯誤資訊(資料報沒有準備好的情況下),此時當前程序可以做其它的事情,不用阻塞;

從圖中可以得知,前三次系統呼叫時都沒有資料可以返回,核心均返回一個 EWOULDBLOCK,並且不會阻塞當前程序,直到第四次詢問核心緩衝區是否有資料的時候,此時核心緩衝區中已經有一個準備好的資料,因此將核心資料複製到使用者空間,此時系統呼叫則返回成功;

當一個應用程序像這樣對一個非阻塞socket迴圈呼叫 recv/recvfrom 時,則稱為輪詢;應用程序持續輪詢核心,以檢視某個操作是否就緒,這麼做往往消耗大量的CPU時間。

2.2.2 優點和缺點

  • 優點:相較於阻塞模型,非阻塞不用再等待任務,而是把時間花費到其它任務上,也就是這個當前執行緒同時處理多個任務;

  • 缺點:導致任務完成的響應延遲增大了,因為每隔一段時間才去執行詢問的動作,但是任務可能在兩個詢問動作的時間間隔內完成,這會導致整體資料吞吐量的降低。

2.3 IO多路複用

2.3.1 介紹

有了I/O複用,我們就可以呼叫 select或poll,讓其阻塞在兩個系統呼叫(1.詢問資料是否準備好並且直到資料準備好才返回;2.核心是否把資料全部複製完成到使用者程序)中的某一個之上

圖中阻塞於 select 呼叫,等待資料報套接字變為可讀。當select返回套接字可讀這一條件的時候,則呼叫 recvfrom 把所讀資料報復制到應用程序緩衝區;

之前的同步非阻塞方式需要使用者程序不停的輪詢,但是IO多路複用不需要不停的輪詢,而是派別人去幫忙迴圈查詢多個任務的完成狀態,UNIX/Linux 下的 select、poll、epoll 就是幹這個的;select呼叫是核心級別的,select輪詢相對非阻塞的輪詢的區別在於---前者可以等待多個socket,能實現同時對多個IO埠進行監聽,當其中任何一個socket的資料準好了,就能返回進行可讀,然後程序再進行recvform系統呼叫,將資料由核心拷貝到使用者程序,當然這個過程是阻塞的。select或poll呼叫之後,會阻塞程序,與blocking IO阻塞不同在於,此時的select不是等到socket資料全部到達再處理, 而是有了一部分資料(網路上的資料是分組到達的)就會呼叫使用者程序來處理。如何知道有一部分資料到達了呢?監視的事情交給了核心,核心負責資料到達的處理。

我認為上面那句話中存在兩個重要點:1.對多個socket進行監聽,只要任何一個socket資料準備好就返回可讀;2.不等一個socket資料全部到達再處理,而是一部分socket的資料到達了就通知使用者程序;

其實 select、poll、epoll 的原理就是不斷的遍歷所負責的所有的socket完成狀態,當某個socket有資料到達了,就返回可讀並通知使用者程序來處理;

2.3.2 優點和缺點

  • 優點:能夠同時處理多個連線,系統開銷小,系統不需要建立新的額外程序或者執行緒,也不需要維護這些程序和執行緒的執行,降低了系統的維護工作量,節省了系統資源。
  • 缺點:如果處理的連結數目不高的話,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server效能更好,可能延遲還更大。(因為阻塞可以保證沒有延遲,但是多路複用是處理先存在的資料,所以資料的順序則不管,導致處理一個完整的任務的時間上有延遲)

2.3.3 同步非阻塞和多執行緒+同步阻塞

高併發的程式一般使用同步非阻塞方式而非多執行緒 + 同步阻塞方式。要理解這一點,首先要扯到併發和並行的區別。比如去某部門辦事需要依次去幾個視窗,辦事大廳裡的人數就是併發數,而視窗個數就是並行度。也就是說併發數是指同時進行的任務數(如同時服務的 HTTP 請求),而並行數是可以同時工作的物理資源數量(如 CPU 核數)。通過合理排程任務的不同階段,併發數可以遠遠大於並行度,這就是區區幾個 CPU 可以支援上萬個使用者併發請求的奧祕。在這種高併發的情況下,為每個任務(使用者請求)建立一個程序或執行緒的開銷非常大。而同步非阻塞方式可以把多個 IO 請求丟到後臺去,這就可以在一個程序裡服務大量的併發 IO 請求。

2.4 訊號驅動式I/O模型

首先開啟套接字的訊號驅動式IO功能,並且通過 sigaction 系統呼叫安裝一個訊號處理函式,該函式呼叫將立即返回,當前程序沒有被阻塞,繼續工作;當資料報準備好的時候,核心則為該程序產生 SIGIO 的訊號,隨後既可以在訊號處理函式中呼叫 recvfrom 讀取資料報,並且通知主迴圈資料已經準備好等待處理,也可以通知主迴圈讓它讀取資料報;(其實就是一個待讀取的通知和待處理的通知);

2.5 非同步式I/O模型

我們呼叫 aio_read 函式,給核心傳遞描述符、緩衝區指標、緩衝區大小和檔案偏移,並且告訴核心當整個操作完成時如何通知我們。該函式呼叫後立即返回,不被阻塞;

2.6 比較


相關推薦

Java阻塞阻塞以及同步非同步區別

阻塞和非阻塞,同步和非同步1 例子故事:老王燒開水。出場人物:老張,水壺兩把(普通水壺,簡稱水壺;會響的水壺,簡稱響水壺)。老王想了想,有好幾種等待方式1.老王用水壺煮水,並且站在那裡,不管水開沒開,每隔一定時間看看水開了沒。-同步阻塞老王想了想,這種方法不夠聰明。2.老王還

java並發編程(8)原子變量阻塞同步機制

turn 判斷 變量 ntp 機制 tail values 添加 get 原子變量和非阻塞的同步機制 一、鎖的劣勢   1.在多線程下:鎖的掛起和恢復等過程存在著很大的開銷(及時現代的jvm會判斷何時使用掛起,何時自旋等待)   2.volatile:輕量級別的同步機制,

同步異步以及阻塞阻塞區別

結束 線程 同步異步 成功 -s 區別 狀態 得到 概念 一、同步與異步的區別: 同步:一個服務的完成需要依賴其他服務時,只有等待被依賴的服務完成後,才算完成,這是一種可靠的服務序列。要麽成功都成功,失敗都失敗,服務的狀態可以保持一致。 異步:一個服務的完成需要依賴其他

java併發原子操作類(AtomicLong原始碼分析)阻塞演算法

  背景 近年來,在併發演算法領域的大多數研究都側重於非阻塞演算法,這種演算法用底層的原子機器指令(例如比較併發交換指令)代替鎖來確保資料在併發訪問中的一致性。非阻塞演算法被廣泛的用於在作業系統和JVM中實現執行緒/程序排程機制、垃圾回收機制以及鎖和其他併發資料結構。 與基於鎖

JAVA併發程式設計實戰》原子變數阻塞同步機制

引言 即使原子變數沒有用於非阻塞演算法的開發,他們也可以用作一種“更好的”volatile型別變數。原子變數提供了與volatile型別變數相同的記憶體語義,此外還支援原子的更新操作,從而使他們更加適用於實現計數器、序列發生器和統計資料收集等,同時還能比基於鎖

java同步非同步阻塞阻塞的聯絡區別

所謂同步就是一個任務的完成需要依賴另外一個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成,這是一種可靠的任務序列。要麼成功都成功,失敗都失敗,兩個任務的狀態可以保持一致。而非同步是不需要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工作,依賴

Android 網路程式設計同步,非同步,阻塞阻塞

同步:函式沒有執行完不返回,執行緒被掛起;   阻塞:沒有收完資料函式不返回,執行緒也被掛起;  非同步:函式立即返回,通過事件或是訊號通知呼叫者;  非阻塞:函式立即返回,通過select通知呼叫者  同步:函式沒有執行完不返回,執行緒被掛起 阻塞:沒有收完資料函式不返回,執行緒也被掛起 非同步:函

Java多執行緒、同步非同步阻塞阻塞

1、程序和執行緒的概念 程序:執行中的應用程式稱為程序,擁有系統資源(cpu、記憶體) 執行緒:程序中的一段程式碼,一個程序中可以有多段程式碼。本身不擁有資源(共享所在程序的資源); 在java中,程式入口被自動建立為主執行緒,在主執行緒中可以建立多個子執

同步異步以及阻塞阻塞

url href 同步阻塞 必須 html async size sse 輪詢 同步、異步: 概念:消息的通知機制 解釋:涉及到IO通知機制; 所謂同步,就是發起調用後,被調用者處理消息,必須等處理完才直接返回結果,沒處理完之前是不返回的,調用者主動等待結果; 所謂

深入理解阻塞同步IO阻塞異步IO

sam log while循環 不清楚 重要 http 文章 最終 簡單 這兩篇文章分析了Linux下的5種IO模型 http://blog.csdn.net/historyasamirror/article/details/5778378 http://blog.csd

Java 同步與異步-阻塞阻塞理解

blog markdown logs 任務 一段 mar 慢操作 兩個 需要 Java 同步與異步-阻塞與非阻塞理解 Java 中同步與異步,阻塞與非阻塞都是用來形容交互方式,區別在於它們描述的是交互的兩個不同層面。 同步與異步 同步與異步更關註交互雙方是否可以同時工作。以

阻塞式I/0 阻塞式I/O 同步異步詳細介紹

name 比較 基本上 b2c 復制 描述 tab 是把 分享 請求描述: `阻塞/非阻塞` 和 `同步/異步` 不是一個概念。舉幾個簡單的例子。 當進程調用一個進行IO操作的API時(比如read函數),在數據沒有到達前,read 會掛起,進程會卡住。在

什麼是同步非同步,什麼是阻塞阻塞

同步和非同步是針對應用程式和核心的互動而言的,同步指的是使用者程序觸發IO操作並等待或者輪詢的去檢視IO操作是否就緒,而非同步是指使用者程序觸發IO操作以後便開始做自己的事情,而當IO操作已經完成的時候會得到IO完成的通知。 以銀行取款為例: 同步:自己親自出馬持銀行卡到銀行取錢(使用同

阻塞阻塞同步非同步

阻塞和非阻塞 阻塞呼叫是指呼叫結果返回之前,呼叫者會進入阻塞狀態等待。只有在得到結果之後才會返回。 非阻塞呼叫是指在不能立刻得到結果之前,該函式不會阻塞當前執行緒,而會立刻返回。   2.同步與非同步 同步和非同步關注的是訊息通訊機制 (synchronous c

同步非同步_阻塞阻塞

阻塞和非阻塞 執行緒去請求資源時,遇到資源正在處理還未準備就緒的情況的兩種處理方式: 阻塞:執行緒等待該資源準備就緒。呼叫結果返回之前,當前執行緒會被掛起。 非阻塞:執行緒發現該資源正在處理,會去請求別的資源 同步和非同步 訪問資料的兩種機制: 同步:請求資料時,等

談IO中的阻塞阻塞同步非同步及三種IO模型

什麼是同步和非同步?        燒水,我們都是通過熱水壺來燒水的。在很久之前,科技還沒有這麼發達的時候,如果我們要燒水,需要把水壺放到火爐上,我們通過觀察水壺內的水的沸騰程度來判斷水有沒有燒開。隨著科技的發展,現在市面上的水壺都有了提醒功能,當我們把水壺插電

談IO中的阻塞阻塞同步異步及三種IO模型

狀態 阻塞io 舉例 最大的 data- str 被調用 當我 返回 什麽是同步和異步? 燒水,我們都是通過熱水壺來燒水的。在很久之前,科技還沒有這麽發達的時候,如果我們要燒水,需要把水壺放到火爐上,我們通過觀察水壺內的水的沸騰程度來判斷水有沒有燒開。隨著科

java nio及作業系統底層原理同步非同步阻塞阻塞

目錄 IO基本概念 同步,非同步,阻塞,非阻塞 同步與非同步 阻塞與非阻塞 IO模型(Reference Link) 阻塞I/O模型 非阻塞I/O模型 I/O複用模型 訊號驅動非同步I/O模型 非同步I/O模型 總結 AIO,BIO,NIO Jav

Java-併發-佇列-阻塞阻塞佇列總結

Java-併發-佇列-阻塞和非阻塞佇列總結 轉載宣告: 本文系轉載自以下文章: Java 併發 — 阻塞佇列總結 作者: thgreat java中併發集合 作者:hy飛無 0x01 摘要 本文會對java併發包內的常用重要阻塞/非阻塞佇列進行總結。

同步佇列(阻塞佇列阻塞佇列)

在併發程式設計中,很多情況下需要使用執行緒安全的佇列。而實現執行緒安全的佇列有兩種實現方式 1、使用阻塞演算法:使用阻塞演算法的佇列可以用一個鎖(入隊和出隊使用同一把鎖)或兩個鎖(入隊和出隊用不同的鎖)等方式來實現(基於鎖的演算法會帶來一些活躍度失敗的風險。如果執行緒在持有