Java線程池隊列PriorityBlockingQueue和SynchronousQueue詳解
正文
public enum QueueTypeEnum { ARRAY_BLOCKING_QUEUE(1, "ArrayBlockingQueue"), LINKED_BLOCKING_QUEUE(2, "LinkedBlockingQueue"), DELAY_QUEUE(3, "DelayQueue"), PRIORITY_BLOCKING_QUEUE(4, "PriorityBlockingQueue"), SYNCHRONOUS_QUEUE(5, "SynchronousQueue"), LINKED_TRANSFER_QUEUE(6, "LinkedTransferQueue"), LINKED_BLOCKING_DEQUE(7, "LinkedBlockingDeque"), VARIABLE_LINKED_BLOCKING_QUEUE(8, "VariableLinkedBlockingQueue"), MEMORY_SAFE_LINKED_BLOCKING_QUEUE(9, "MemorySafeLinkedBlockingQueue"); }
PriorityBlockingQueue阻塞優先隊列
一個支持優先級排序的無界阻塞隊列;對元素沒有要求,可以實現Comparable接口也可以提供 Comparator來對隊列中的元素進行比較。通過構造函數傳入的對象來判斷,傳入的對象必須實現comparable接口,並重寫compareTo方法。可以按照自然排序或自定義排序的順序在隊列中對元素進行排序。
例如新建對象Person:
public class Person implements Comparable<Person>{ private int id; @Override public int compareTo(Person person) { return this.id > person.getId() ? 1 : ( this.id < person.getId() ? -1 :0); } }
每次添加一個元素,PriorityBlockingQueue中的person都會執行compareTo方法進行排序,但是隻是把第一個元素排在首位,其他元素按照隊列的一系列復雜算法排序。這就保障瞭每次獲取到的元素都是經過排序的第一個元素。
SynchronousQueue
SynchronousQueue是一個不存儲元素的阻塞隊列,是BlockingQueue的一種,SynchronousQueue線程安全的。SynchronousQueue和其他的BlockingQueue不同的是SynchronousQueue的capacity是0。即SynchronousQueue不存儲任何元素。消費者線程調用 take() 方法的時候就會發生阻塞,直到有一個生產者線程生產瞭一個元素,消費者線程就可以拿到這個元素並返回;生產者線程調用 put() 方法的時候也會發生阻塞,直到有一個消費者線程消費瞭一個元素,生產者才會返回。
SynchronousQueue內部並沒有數據緩存空間,你不能調用peek()方法來看隊列中是否有數據元素,因為數據元素隻有當你試著取走的時候才可能存在,不取走而隻想偷 窺一下是不行的,當然遍歷這個隊列的操作也是不允許的。
隊列頭元素是第一個排隊要插入數據的線程,而不是要交換的數據。數據是在配對的生產者和消費者線程之間直接傳遞的,並不會將數據緩沖到隊列中。可以這樣來理解:生產者和消費者互相等待對方,握手,然後一起離開。
SynchronousQueue的一個使用場景是在線程池裡。Executors.newCachedThreadPool()就使用瞭SynchronousQueue,這個線程池根據需要(新任務到來時)創建新的線程,如果有空閑線程則會重復使用,線程空閑瞭60秒後會被回收。
以上就是Java線程池隊列PriorityBlockingQueue和SynchronousQueue詳解的詳細內容,更多關於Java線程池隊列的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Java線程池隊列LinkedBlockingDeque
- Java線程池隊列LinkedTransferQueue示例詳解
- Java中PriorityQueue實現最小堆和最大堆的用法
- Java 阻塞隊列BlockingQueue詳解
- 淺談Java中Collections.sort對List排序的兩種方法