怎样理解阻塞非阻塞与同步异步的区别?
- 發現很多人對這兩個概念往往混為一談(包括本人,不是很理解)。
- 阻塞”與"非阻塞"與"同步"與“異步"不能簡單的從字面理解,提供一個從分布式系統角度的回答。
一 ?定義理解方式
?1.同步與異步
? 同步和異步關注的是消息通信機制?(synchronous communication/ asynchronous communication),所謂同步,就是在發出一個*調用*時,在沒有得到結果之前,該*調用*就不返回。但是一旦調用返回,就得到返回值了。換句話說,就是由*調用者*主動等待這個*調用*的結果
而異步則是相反,*調用*在發出之后,這個調用就直接返回了,所以沒有返回結果。換句話說,當一個異步過程調用發出后,調用者不會立刻得到結果。而是在*調用*發出后,*被調用者*通過狀態、通知來通知調用者,或通過回調函數處理這個調用。典型的異步編程模型比如Node.js
舉個通俗的例子:你打電話問書店老板有沒有《分布式系統》這本書,如果是同步通信機制,書店老板會說,你稍等,”我查一下",然后開始查啊查,等查好了(可能是5秒,也可能是一天)告訴你結果(返回結果)。
而異步通信機制,書店老板直接告訴你我查一下啊,查好了打電話給你,然后直接掛電話了(不返回結果)。然后查好了,他會主動打電話給你。在這里老板通過“回電”這種方式來回調。
2. 阻塞與非阻塞
阻塞和非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態。
??阻塞調用是指調用結果返回之前,當前線程會被掛起。調用線程只有在得到結果之后才會返回。非阻塞調用指在不能立刻得到結果之前,該調用不會阻塞當前線程。
?
還是上面的例子你打電話問書店老板有沒有《分布式系統》這本書,你如果是阻塞式調用,你會一直把自己“掛起”,直到得到這本書有沒有的結果,如果是非阻塞式調用,你不管老板有沒有告訴你,你自己先一邊去玩了, 當然你也要偶爾過幾分鐘check一下老板有沒有返回結果。
在這里阻塞與非阻塞與是否同步異步無關。跟老板通過什么方式回答你結果無關。
二 老張煮開水(經典理解)
老張愛喝茶,廢話不說,煮開水。出場人物:老張,水壺兩把(普通水壺,簡稱水壺;會響的水壺,簡稱響水壺)。1 老張把水壺放到火上,立等水開。(同步阻塞) 老張覺得自己有點傻 2 老張把水壺放到火上,去客廳看電視,時不時去廚房看看水開沒有。(同步非阻塞) 老張還是覺得自己有點傻,于是變高端了,買了把會響笛的那種水壺。水開之后,能大聲發出嘀~~~~的噪音。 3 老張把響水壺放到火上,立等水開。(異步阻塞) 老張覺得這樣傻等意義不大 4 老張把響水壺放到火上,去客廳看電視,水壺響之前不再去看它了,響了再去拿壺。(異步非阻塞)
老張覺得自己聰明了。 所謂同步異步,只是對于水壺而言。 1.?普通水壺,同步;響水壺,異步。 2. 雖然都能干活,但響水壺可以在自己完工之后,提示老張水開了。這是普通水壺所不能及的。 3.?同步只能讓調用者去輪詢自己,才能提高盡量效率(情況2中),造成老張效率的低下。 所謂阻塞非阻塞,僅僅對于老張而言。 1.?立等的老張,阻塞;看電視的老張,非阻塞。 2.?情況1和情況3中老張就是阻塞的,媳婦喊他都不知道。雖然3中響水壺是異步的,可對于一直在等待的老張沒有太大的意義。所以一般異步是配合非阻塞使用的,這樣才能發揮異步的效用。
三 網絡中請求
A.概念
阻塞非阻塞:?請求不能立即得到應答,需要等待,那就是阻塞;否則可以理解為非阻塞。
同步異步:?某業務需要甲乙甚至多方合作的時候,
1.?總是按照“甲方請求一次,乙方應答一次”這樣的有序序列處理業務,只有當“一次請求一次應答”的過程結束才可以發生下一次的“一次請求一次應答”,那么就說他們采用的是同步。(同步IO中,對同一個描述符的操作必須是有序的)
2.?如果甲方只要有需要,就會發送請求,不管上次請求有沒有得到乙方應答。而乙方只要甲方有請求就會接受,不是等這次請求處理完畢再接受甲方新請求。這樣請求應答分開的序列,就可以認為是異步。異步情況下,請求和應答不需要一致進行,可能甲方后請求的業務,卻先得到乙方的應答。同步是線性的,而異步可以認為是并發的。(異步IO中,異步IO可以允許多方同時對同一個描述符發送IO請求,或者一次發多個請求,當然有機制保證如何區分這些請求,)
3.?我去買一本書,立即買到了,或者沒有就走了,這就是非阻塞;(編程中設置IO成非阻塞,返回后再去檢查描述符,或者等待通知,然后再去讀取。相當于老板告訴我可以先忙點別的,過一會再來問問,或者老板通知我。但期間這個窗口(文件描述符)別人是用不了的)("立即買到了"在IO中也需要等待,不能算非阻塞IO)
4.?如果恰好書店沒有,我就等一直等到書店有了這本書買到了才走,這就是阻塞;而排在我后面的人呢只有我買到了書后才能再買書了。
5. 如果書店恰好沒有,我就告訴書店老板,書來了告訴我一聲讓我來取或者直接送到我家,然后我就走了,去做別的事了,這就是異步。這時候如果很多人來買書,都是老板登記一下完事。 (從IO角度來說,“告訴我來取”,這個近似于信號驅動IO,不能算異步IO。必須書送到我家才算是異步,如果不送到我家,我想看這本書之前,終究還是需要我跑一趟)
?
四 Java程序中的同步異步
Java中同步異步和多線程相關,同步的方法可以認為是線程安全的,同樣也是效率低得一類。異步的方式大多數是線程不安全的。
經常看到介紹 ArrayList 和HashMap是異步,Vector和HashTable是同步,這里同步是線程安全的,異步不是線程安全的,舉例說明:
當創建一個Vector對象時候: Vector ve=new Vector();
ve.add("1");(方法返回之前,其他線程不能操作ve對象)
當在多線程程序中,第一個線程調用修改對象ve的時候,就為其上了鎖,其他線程只有等待。
?
當創建一個ArrayList對象時候:ArrayList list=new ArrayList();
list.add("1"); (方法返回之前,其他線程可以操作list對象,例如list.add("2"))
當在多線程程序中,第一個線程調用修改對象list的時候,沒有為其上鎖,其他線程訪問時就會出現數據異常。
?
1.?同步(Sync)
A線程要請求某個資源,但是此資源正在被B線程使用中,因為同步機制存在,A線程請求 不到,怎么辦,A線程只能等待下去
2.?異步(Async) A線程要請求某個資源,但是此資源正在被B線程使用中,因為沒有同步機制存在,A線程 仍然請求的到,A線程無需等待顯然,同步最最安全,最保險的。而異步不安全,容易導致死鎖,這樣一個線程死掉就會導致整個進程崩潰,但沒有同步機制的存在,性能會有所提升
java中實現多線程
1)繼承Thread,重寫里面的run方法
2)實現runnable接口
比較推薦后者,第一,java有單繼承的限制,第二,還可以隔離代碼線程池?要知道在計算機中任何資源的創建,包括線程,都需要消耗系統資源的。在WEB服務中,對于web服 務器的響應速度必須要盡可能的快,這就容不得每次在用戶提交請求按鈕后,再創建線程提供服務 。為了減少用戶的等待時間,線程必須預先創建,放在線程池中,線程池可以用HashTable這種數 據結構來實現,看了Apach HTTP服務器的線程池的源代碼,用是就是HashTable,KEY用線程對象, value 用ControlRunnable,ControlRunnable是線程池中唯一能干活的線程,是它指派線程池中的 線程對外提供服務。 出于安全考慮,Apach HTTP服務器的線程池它是同步的。聽說weblogic有異步的實現方式,沒有研 究過,不敢確定
--------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------
一、關鍵字:
thread(線程)、thread-safe(線程安全)、intercurrent(并發的) synchronized(同步的)、asynchronized(異步的)、 volatile(易變的)、atomic(原子的)、share(共享)
二、概念:
1、 什么時候必須同步?什么叫同步?如何同步?
要跨線程維護正確的可見性,只要在幾個線程之間共享非 final 變量,就必須使用 synchronized(或 volatile)以確保一個線程可以看見另一個線程做的更改。為了在線程之間進行可靠的通信,也為了互斥訪問,同步是必須的。這歸因于java語言規范的內存 模型,它規定了:一個線程所做的變化何時以及如何變成對其它線程可見。
因為多線程將異步行為引進程序,所以在需要同步時,必須有一種方法強制進行。例如:如果2個線 程想要通信并且要共享一個復雜的數據結構,如鏈表,此時需要確保它們互不沖突,也就是必須阻 止B線程在A線程讀數據的過程中向鏈表里面寫數據(A獲得了鎖,B必須等A釋放了該鎖)。
為了達到這個目的,java在一個舊的的進程同步模型——監控器(Monitor)的基礎上實現了一個巧 妙的方案:監控器是一個控制機制,可以認為是一個很小的、只能容納一個線程的盒子,一旦一個 線程進入監控器,其它的線程必須等待,直到那個線程退出監控為止。通過這種方式,一個監控器 可以保證共享資源在同一時刻只可被一個線程使用。這種方式稱之為同步。(一旦一個線程進入一 個實例的任何同步方法,別的線程將不能進入該同一實例的其它同步方法,但是該實例的非同步方 法仍然能夠被調用)。
同步和多線程關系:沒多線程環境就不需要同步;有多線程環境也不一定需要同步。
鎖提供了兩種主要特性:互斥(mutual exclusion)和可見性(visibility)。
互斥即一次只允許一個線程持有某個特定的鎖,因此可使用該特性實現對共享數據的協調訪問協議 ,這樣,一次就只有一個線程能夠使用該共享數據。
可見性要更加復雜一些,它必須確保釋放鎖之前對共享數據做出的更改對于隨后獲得該鎖的另一個 線程是可見的 —— 如果沒有同步機制提供的這種可見性保證,線程看到的共享變量可能是修改前 的值或不一致的值,這將引發許多嚴重問題
小結:為了防止多個線程并發對同一數據的修改,所以需要同步,否則會造成數據不一致(就是所 謂的:線程安全。如java集合框架中Hashtable和Vector是線程安全的。我們的大部分程序都不是線 程安全的,因為沒有進行同步,而且我們沒有必要,因為大部分情況根本沒有多線程環境)。
未完。待續. . . 參考:https://www.zhihu.com/question/19732473 參考:http://www.cnblogs.com/mengyuxin/p/5358364.html
轉載于:https://www.cnblogs.com/chihirotan/p/6028276.html
總結
以上是生活随笔為你收集整理的怎样理解阻塞非阻塞与同步异步的区别?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件项目验收的准备工作
- 下一篇: 网址集锦