Java同步和異步,阻塞和非阻塞

同步和異步、阻塞和非阻塞

同步和異步關注的是消息通信機制.

同步是指: 發送方發出數據後, 等待接收方發回響應後才發下一個數據包的通訊方式. 就是在發出一個調用時, 在沒有得到結果之前, 該調用就不返回, 但是一旦調用返回, 就得到返回值了. 也就是由"調用者"主動等待這個"調用"的結果.

異步是指: 發送方發出數據後, 不等待接收方發回響應, 接著發送下個數據包的通訊方式. 當一個異步過程調用發出後, 調用者不會立刻得到結果. 而是在調用發出後, "被調用者"通過狀態、通知來通知調用者, 或通過回調函數處理這個調用.

阻塞和非阻塞屬於進程API執行動作的方式, 關注的是程序在等待調用結果時的狀態.

阻塞是指: 調用結果返回之前, 當前線程會被掛起. 函數只有在得到結果之後才會返回, 線程需要等待結果.

非阻塞是指: 與阻塞的概念相對應, 指在不能立刻得到結果之前, 該函數不會阻塞當前線程, 而會立刻返回. 線程不需要等待結果.

Java中的同步和異步

定義: 任務A, 任務B

同步: 任務A和任務B之間有關聯, 例如任務B中途要給任務A一個數字, 那麼任務A或許需要等待任務B生產這個數, 任務A需要等待任務B的這個動作叫做同步.

異步: 事件A和事件B之間沒有關聯, 是相互獨立的, 那麼相互都不用管對方幹了什麼.

定義: 線程A和線程B, 分別在執行任務A和任務B

阻塞: 線程A需要等待線程B, 於是線程A在等待這個數的步驟上被掛起, 不能分到cpu, 不能執行, 這樣被稱為阻塞.

非阻塞: 線程同樣需要線程B給一個數, 但是線程A僅僅告知線程B要給這個數, 並沒有馬上就要使用這個數, 此時線程A沒有被掛起, 仍然能分到cpu, 仍然能執行, 這樣被稱為非阻塞.

下面給出Java代碼的例子.

同步阻塞:

int i = System.in.read();

當命令終端沒有輸入時, 調用該方法的線程被阻塞 ,表現出和終端同步.

異步非阻塞:

Future future = threadPool.submit(Callable callable);
// doSomething
future.get();

callable內的任務結果沒有馬上需要的必要, 於是調用submit()方法馬上返回一個實現Future的存根. callable任務對於當前線程是異步的, 不需要阻塞當前線程.

但是到左後縣城需要callable任務的結果時, 就需要同步了, get()方法通過阻塞來實現.

同步非阻塞:

concurrentLinkedQueue.offer((T) t);

該過程一個元素需要入隊列, 該併發隊列為了讓當前線程不阻塞而又能正確入隊, 使用CAS算法實現的樂觀鎖循環嘗試入隊. offer()方法並沒有阻塞當前線程, 而又希望同步, 於是通過循環來實現, 最終實現同步非阻塞.

異步阻塞:

沒有例子. 阻塞就是用來實現同步的,這和同步阻塞有什麼區別, 那實現它還有什麼用呢?


分享到:


相關文章: