A. 同步非同步,阻塞和非阻塞該怎樣理解
以銀行排隊為例
1 同步阻塞
銀行不給票,直接排隊
2 同步非阻塞
銀行排隊,在隊伍里打電話,時不時看隊伍到自己了。
這里分為兩個動作,排隊時不時為主,打電話為輔。
這樣在代碼里頭顯示為,一個死循環,不斷輪詢到自己沒有,這個循環中還能做其他動作,就是打電話,或者說抽煙。和1不同,1隻能時不時看,也就是輪詢,不斷的把自己懟埠監聽,只做一個東西,因為他被阻塞了。
3 非同步阻塞
老實說,我覺得跟1有點像,這個例子還是銀行的,這個銀行升級了,會發票給你,這個小票替代你排隊,到你了銀行會叫你,這就是非同步。
但是這時候你發現被阻塞了,不能抽煙,不能出去走走,不去順路在隔壁買雞排吃,我的媽,這和1到底有什麼分別?!
老實說個人覺得沒有分別,但是在程序里大概是這樣顯示的,不用循環了,不用一次次去埠懟著了,起個函數線程只需要等待通知,就可以接收亂七八糟的東西。
嗨呀,好氣啊,這樣做有個卵用。
有用哈,雖然線程掛起等待,但是cpu沒閑著啊,該咋地還是咋地,省資源了撒(心裡話:還是沒卵用
4 非同步非阻塞
拿了小票排隊,然後去隔壁買雞排,在門口抽根煙,吃完雞排發現銀行還沒叫我,嗨呀,好氣啊,銀行怎麼這么辣雞,排個隊那麼卵久的
B. java 中 阻塞隊列 非阻塞隊列 和普通隊列的區別是什麼
阻塞隊列與普通隊列的區別在於,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來,如從隊列中移除一個或者多個元素,或者完全清空隊列.
1.ArrayDeque, (數組雙端隊列)
2.PriorityQueue, (優先順序隊列)
3.ConcurrentLinkedQueue, (基於鏈表的並發隊列)
4.DelayQueue, (延期阻塞隊列)(阻塞隊列實現了BlockingQueue介面)
5.ArrayBlockingQueue, (基於數組的並發阻塞隊列)
6.LinkedBlockingQueue, (基於鏈表的FIFO阻塞隊列)
7.LinkedBlockingDeque, (基於鏈表的FIFO雙端阻塞隊列)
8.PriorityBlockingQueue, (帶優先順序的無界阻塞隊列)
9.SynchronousQueue (並發同步阻塞隊列)
阻塞隊列和生產者-消費者模式
阻塞隊列(Blocking queue)提供了可阻塞的put和take方法,它們與可定時的offer和poll是等價的。如果Queue已經滿了,put方法會被阻塞直到有空間可用;如果Queue是空的,那麼take方法會被阻塞,直到有元素可用。Queue的長度可以有限,也可以無限;無限的Queue永遠不會充滿,所以它的put方法永遠不會阻塞。
阻塞隊列支持生產者-消費者設計模式。一個生產者-消費者設計分離了「生產產品」和「消費產品」。該模式不會發現一個工作便立即處理,而是把工作置於一個任務(「to do」)清單中,以備後期處理。生產者-消費者模式簡化了開發,因為它解除了生產者和消費者之間相互依賴的代碼。生產者和消費者以不同的或者變化的速度生產和消費數據,生產者-消費者模式將這些活動解耦,因而簡化了工作負荷的管理。
生產者-消費者設計是圍繞阻塞隊列展開的,生產者把數據放入隊列,並使數據可用,當消費者為適當的行為做准備時會從隊列中獲取數據。生產者不需要知道消費者的省份或者數量,甚至根本沒有消費者—它們只負責把數據放入隊列。類似地,消費者也不需要知道生產者是誰,以及是誰給它們安排的工作。BlockingQueue可以使用任意數量的生產者和消費者,從而簡化了生產者-消費者設計的實現。最常見的生產者-消費者設計是將線程池與工作隊列相結合。
阻塞隊列簡化了消費者的編碼,因為take會保持阻塞直到可用數據出現。如果生產者不能足夠快地產生工作,讓消費者忙碌起來,那麼消費者只能一直等待,直到有工作可做。同時,put方法的阻塞特性也大大地簡化了生產者的編碼;如果使用一個有界隊列,那麼當隊列充滿的時候,生產者就會阻塞,暫不能生成更多的工作,從而給消費者時間來趕進進度。
有界隊列是強大的資源管理工具,用來建立可靠的應用程序:它們遏制那些可以產生過多工作量、具有威脅的活動,從而讓你的程序在面對超負荷工作時更加健壯。
雖然生產者-消費者模式可以把生產者和消費者的代碼相互解耦合,但是它們的行為還是間接地通過共享隊列耦合在一起了
類庫中包含一些BlockingQueue的實現,其中LinkedBlockingQueue和ArrayBlockingQueue是FIFO隊列,與 LinkedList和ArrayList相似,但是卻擁有比同步List更好的並發性能。PriorityBlockingQueue是一個按優先順序順序排序的隊列,當你不希望按照FIFO的屬性處理元素時,這個PriorityBolckingQueue是非常有用的。正如其他排序的容器一樣,PriorityBlockingQueue可以比較元素本身的自然順序(如果它們實現了Comparable),也可以使用一個 Comparator進行排序。
最後一個BlockingQueue的實現是SynchronousQueue,它根本上不是一個真正的隊列,因為它不會為隊列元素維護任何存儲空間。不過,它維護一個排隊的線程清單,這些線程等待把元素加入(enqueue)隊列或者移出(dequeue)隊列。因為SynchronousQueue沒有存儲能力,所以除非另一個線程已經准備好參與移交工作,否則put和take會一直阻止。SynchronousQueue這類隊列只有在消費者充足的時候比較合適,它們總能為下一個任務作好准備。
非阻塞演算法
基於鎖的演算法會帶來一些活躍度失敗的風險。如果線程在持有鎖的時候因為阻塞I/O,頁面錯誤,或其他原因發生延遲,很可能所有的線程都不能前進了。
一個線程的失敗或掛起不應該影響其他線程的失敗或掛起,這樣的演算法成為非阻塞(nonblocking)演算法;如果演算法的每一個步驟中都有一些線程能夠繼續執行,那麼這樣的演算法稱為鎖自由(lock-free)演算法。在線程間使用CAS進行協調,這樣的演算法如果能構建正確的話,它既是非阻塞的,又是鎖自由的。非競爭的CAS總是能夠成功,如果多個線程以一個CAS競爭,總會有一個勝出並前進。非阻塞演算法堆死鎖和優先順序倒置有「免疫性」(但它們可能會出現飢餓和活鎖,因為它們允許重進入)。
非阻塞演算法通過使用低層次的並發原語,比如比較交換,取代了鎖。原子變數類向用戶提供了這些底層級原語,也能夠當做「更佳的volatile變數」使用,同時提供了整數類和對象引用的原子化更新操作
C. c++非阻塞多線程實例應用的演算法有哪些
多線程非阻塞模式到現在算是告一段落吧 雖然還有一些小的bug需要修正 總結一下 准備向後面進發
實現功能: 本程序主要實現遠程計算的功能 通過非阻塞套接字和多線程的結合 讓通信變得高效 伺服器通過維護一個客戶端鏈表來實現對多個客戶響應 客戶端自身驗證表達式的正確性 當輸入Byebye時 伺服器回復OK 此時客戶端斷開連接退出
總結:
不管用何種方式通信 相關聯的幾個線程總會用一個變數來控制所有的其他線程
對於非阻塞套接字 Recv Send Connect Accept等都需要套上一個基於共同控制變數或者永真的循環來實現對WSAEWOULDBLOCK的返回重試
對於通過事件信號量來通知的兩個線程 例如生產者 消費者(生產者生產好了通過hEvent通知消費者) 當生產者退出時 一定要通過該信號量來通知消費者 以免消費者阻塞於WaitForSingleObject 而消費者在等到信號量時 也一定要檢測生產者是否已經退出(或者是說在這里的斷開了連接) 以免發送或接收未知的數據
對於有信號量控制的兩個同步線程 要注意是否有共同訪問的數據 要時刻記得對數據進行互斥訪問
D. Java:什麼叫做同步非阻塞IO呢
這個IO不用等待對方返回結果,打開IO指令執行完成後,會繼續執行指令後面的操作,當對方返回數據後會出發一個事件,告訴你數據回來了,例如使用selector的非阻塞IO.你應當看看java.nio.
E. java怎麼實現同步非阻塞
1.非阻塞演算法
非阻塞演算法屬於並發演算法,它們可以安全地派生它們的線程,不通過鎖定派生,而是通過低級的原子性的硬體原生形式 —— 例如比較和交換。非阻塞演算法的設計與實現極為困難,但是它們能夠提供更好的吞吐率,對生存問題(例如死鎖和優先順序反轉)也能提供更好的防禦。使用底層的原子化機器指令取代鎖,比如比較並交換(CAS,compare-and-swap).
2.悲觀技術
獨占鎖是一種悲觀的技術.它假設最壞的情況發生(如果不加鎖,其它線程會破壞對象狀態),即使沒有發生最壞的情況,仍然用鎖保護對象狀態.
3.樂觀技術
依賴沖突監測.先更新,如果監測發生沖突發生,則放棄更新後重試,否則更新成功.現在處理器都有原子化的讀-改-寫指令,比如比較並交換(CAS,compare-and-swap).
4.CAS操作
CAS有3個操作數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改為B,否則什麼都不做。CAS典型使用模式是:首先從V中讀取A,並根據A計算新值B,然後再通過CAS以原子方式將V中的值由A變成B(只要在這期間沒有任何線程將V的值修改為其他值)。
清單 3. 說明比較並交換的行為(而不是性能)的代碼
public class SimulatedCAS {
private int value;
public synchronized int getValue() { return value; }
public synchronized int compareAndSwap(int expectedValue, int newValue) {
int oldValue = value;
if (value == expectedValue)
value = newValue;
return oldValue;
}
}
清單 4. 使用比較並交換實現計數器
public class CasCounter {
private SimulatedCAS value;
public int getValue() {
return value.getValue();
}
public int increment() {
int oldValue = value.getValue();
while (value.compareAndSwap(oldValue, oldValue + 1) != oldValue)
oldValue = value.getValue();
return oldValue + 1;
}
}
5.原子變數
原子變數支持不用鎖保護就能原子性更新操作,其底層用CAS實現。共有12個原子變數,可分為4組:標量類、更新器類、數組類以及復合變數類。最常用的原子變數就是標量類:AtomicInteger、AtomicLong、AtomicBoolean以及AtomicReference。所有類型都支持CAS。
6.性能比較:鎖與原子變數
在中低程度的競爭下,原子變數能提供很高的可伸縮性,原子變數性能超過鎖;而在高強度的競爭下,鎖能夠更有效地避免競爭,鎖的性能將超過原子變數的性能。但在更真實的實際情況中,原子變數的性能將超過鎖的性能。
F. 如何通過socket消息隊列機制實現同步非阻塞與非同步阻塞優缺點
public class Calcul {
public static void main(String[] args) {
circularArea();
}
public static void circularArea(){
int r=2;
float π=3.14f;
float circularArea = π*r*r;
System.out.println(circularArea);
}
G. 名詞解釋:同步、非同步、阻塞和非阻塞
同步1.同時起步,協調一致。 2.物理學名詞。兩個或幾個隨時間變化的量,在變化過程中保持一定的相對關系. 非同步則反之..
阻塞 1.水流、交通等因被某物堵塞而不能通過。 2.閉塞不通。 3.使堵塞不通。用於抽象事物。 非阻塞則反之
H. 阻塞非阻塞,同步和非同步的區別
首先來解釋同步和非同步的概念,這兩個概念與消息的通知機制有關.
舉個例子,比如我去銀行辦理業務,可能選擇排隊等候,也可能取一個小紙條上面有我的號碼,等到排到我這一號時由櫃台的人通知我輪到我去辦理業務了.
前者(排隊等候)就是同步等待消息,而後者(等待別人通知)就是非同步等待消息.在非同步消息處理中,等待消息者(在這個例子中就是等待辦理業務的人)往往注冊一個回調機制,在所等待的事件被觸發時由觸發機制(在這里是櫃台的人)通過某種機制(在這里是寫在小紙條上的號碼)找到等待該事件的人.
而在實際的程序中,同步消息處理就好比簡單的read/write操作,它們需要等待這兩個操作成功才能返回;而非同步處理機制就是類似於select/poll之類的多路復用IO操作,當所關注的消息被觸發時,由消息觸發機制通知觸發對消息的處理.
其次再來解釋一下阻塞和非阻塞,這兩個概念與程序等待消息(無所謂同步或者非同步)時的狀態有關.
繼續上面的那個例子,不論是排隊還是使用號碼等待通知,如果在這個等待的過程中,等待者除了等待消息之外不能做其它的事情,那麼該機制就是阻塞的,表現在程序中,也就是該程序一直阻塞在該函數調用處不能繼續往下執行.相反,有的人喜歡在銀行辦理這些業務的時候一邊打打電話發發簡訊一邊等待,這樣的狀態就是非阻塞的,因為他(等待者)沒有阻塞在這個消息通知上,而是一邊做自己的事情一邊等待.但是需要注意了,第一種同步非阻塞形式實際上是效率低下的,想像一下你一邊打著電話一邊還需要抬頭看到底隊伍排到你了沒有,如果把打電話和觀察排隊的位置看成是程序的兩個操作的話,這個程序需要在這兩種不同的行為之間來回的切換,效率可想而知是低下的;而後者,非同步非阻塞形式卻沒有這樣的問題,因為打電話是你(等待者)的事情,而通知你則是櫃台(消息觸發機制)的事情,程序沒有在兩種不同的操作中來回切換.
很多人會把同步和阻塞混淆,我想是因為很多時候同步操作會以阻塞的形式表現出來,比如很多人會寫阻塞的read/write操作,但是別忘了可以對fd設置O_NONBLOCK標志位,這樣就可以將同步操作變成非阻塞的了;同樣的,很多人也會把非同步和非阻塞混淆,因為非同步操作一般都不會在真正的IO操作處被阻塞,比如如果用select函數,當select返回可讀時再去read一般都不會被阻塞,就好比當你的號碼排到時一般都是在你之前已經沒有人了,所以你再去櫃台辦理業務就不會被阻塞.
I. 怎樣理解阻塞非阻塞與同步非同步的區別
「阻塞」與"非阻塞"與"同步"與「非同步"不能簡單的從字面理解,提供一個從分布式系統角度的回答。
1.同步與非同步
同步和非同步關注的是消息通信機制 (synchronous communication/ asynchronous communication)
所謂同步,就是在發出一個*調用*時,在沒有得到結果之前,該*調用*就不返回。但是一旦調用返回,就得到返回值了。
換句話說,就是由*調用者*主動等待這個*調用*的結果。
而非同步則是相反,*調用*在發出之後,這個調用就直接返回了,所以沒有返回結果。換句話說,當一個非同步過程調用發出後,調用者不會立刻得到結果。而是在*調用*發出後,*被調用者*通過狀態、通知來通知調用者,或通過回調函數處理這個調用。
典型的非同步編程模型比如Node.js
舉個通俗的例子:
你打電話問書店老闆有沒有《分布式系統》這本書,如果是同步通信機制,書店老闆會說,你稍等,」我查一下",然後開始查啊查,等查好了(可能是5秒,也可能是一天)告訴你結果(返回結果)。
而非同步通信機制,書店老闆直接告訴你我查一下啊,查好了打電話給你,然後直接掛電話了(不返回結果)。然後查好了,他會主動打電話給你。在這里老闆通過「回電」這種方式來回調。
2. 阻塞與非阻塞
阻塞和非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態.
阻塞調用是指調用結果返回之前,當前線程會被掛起。調用線程只有在得到結果之後才會返回。
非阻塞調用指在不能立刻得到結果之前,該調用不會阻塞當前線程。
還是上面的例子,
你打電話問書店老闆有沒有《分布式系統》這本書,你如果是阻塞式調用,你會一直把自己「掛起」,直到得到這本書有沒有的結果,如果是非阻塞式調用,你不管老闆有沒有告訴你,你自己先一邊去玩了, 當然你也要偶爾過幾分鍾check一下老闆有沒有返回結果。
在這里阻塞與非阻塞與是否同步非同步無關。跟老闆通過什麼方式回答你結果無關。