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其它相關文章!

推薦閱讀: