阻塞佇列 生產者-消費者模式 竊取工作模式(java併發程式設計實踐讀書筆記二) 阿新 • • 發佈:2019-02-14 阻塞佇列 生產者-消費者模式 竊取工作模式 生產者-消費者模式 簡化了開發,因為它解除了生產者類和消費者類之間相互依賴的程式碼;解耦不同速度的生產,消費等活動。 圍繞佇列展開設計,生產者把資料放進佇列,不用考慮消費者的消費能力,甚至可以根本沒有消費者。類似的,消費者也不需要知道生產者是誰,只要從佇列中獲取資料即可。 阻塞佇列可以使用任意數量的生產者和消費者 竊取工作模式 每個消費者都有一個自己的雙端佇列。如果一個消費者完成了自己的雙端佇列中的全部工作,它可以偷取其他雙端佇列中 末尾 的任務 優點:工作的執行緒不會競爭一個共享的任務佇列,所以該模式更具有可伸縮性; 減少競爭,即使要從其他雙端佇列中獲取任務,也是從 末尾 獲取,不會與原本執行緒發生競爭 解決消費者與生產者同體的問題:當一個消費者執行緒在執行任務的過程中,發現了更多的的任務,就把新發現的任務放到自己佇列的末尾(或者其他工作者的佇列中)例如:網路爬蟲在處理一個頁面時,發現了更多新的頁面。 java5.0新增的容器型別 Queue 介面 java.util BlockingQueue 介面 java.util.concurrent 提供了可阻塞的put和take方法,等價於可定時的offer和poll 如果Queue已滿,則put方法會阻塞,直到有空間可用 如果Queue為空,則take方法會阻塞,直到有元素可用 offer 和 poll 接受一個額外的時間引數,在這個時間之內等待,超出這個時間則返回false,操作成功則返回ture 不建議使用add方法增加元素,在空間不足的情況下,add方法丟擲異常,建議單純的新增使用offer BlockingQueue 實現 LinkedBlockingQueue ArrayBlockingQueue 上面兩個是FIFO佇列,類似與LinkedList與ArrayList ,擁有比同步List更好的併發效能 PriorityBlockingQueue 按照優先順序排序的佇列,可以在構造的時候提供一個Compararot,進行排序 SynchronousQueue 一種阻塞佇列,其中每個插入操作必須等待另一個執行緒的對應移除操作 ,反之亦然。同步佇列沒有任何內部容量,甚至連一個佇列的容量都沒有。不能在同步佇列上進行peek ,因為僅在試圖要移除元素時,該元素才存在;除非另一個執行緒試圖移除某個元素,否則也不能(使用任何方法)插入元素;也不能迭代佇列,因為其中沒有元素可用於迭代。 同步佇列類似於 CSP 和 Ada 中使用的 rendezvous 通道。它非常適合於傳遞性設計,在這種設計中,在一個執行緒中執行的物件要將某些資訊、事件或任務傳遞給在另一個執行緒中執行的物件,它就必須與該物件同步。 java6.0新增的容器型別 Deque BlockingDeque 雙端佇列,允許在頭和尾分別進行插入和移除 實現類 ArrayDeque,LinkedBlockingDeque 補充:有界佇列 當生產者的速度大於消費者時,使用沒有邊界的佇列,最終會耗盡記憶體。 使用有界佇列,配合offer方法(可以返回失敗狀態),可以在建立更多靈活的策略 減輕負載 把剩餘的工作條目接入硬碟 減少生產者執行緒 ...