當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Java LinkedBlockingDeque用法及代碼示例


LinkedBlockingDequeJava 中的類是Java集合框架。它是在JDK 1.6中引入的,它屬於java.util.concurrent包。它是一個雙端隊列(雙端隊列)如果線程在雙端隊列為空時嘗試從中取出元素,則會阻塞該線程。它實現了 BlockingDeque 並提供基於鏈接節點的 optionally-bounded 函數。這種可選的有界性是通過在構造函數中傳遞所需的大小來實現的,有助於防止內存浪費。未指定時,默認容量為整數.MAX_VALUE。這個類及其迭代器實現了所有可選方法集合迭代器接口。 LinkedBlockingDeque 提供的實現是線程安全。類中的所有排隊方法都使用原子方式實現其效果ReentrantLock內部。

Java 中的 LinkedBlockingDeque 類是 Deque 接口的線程安全並發實現,它使用鏈表來存儲其元素。 LinkedBlockingDeque 可以用作傳統的堆棧或隊列,具體取決於您用於插入和刪除元素的方法。

以下是如何在 Java 中使用 LinkedBlockingDeque 類的示例:

Java


import java.util.concurrent.LinkedBlockingDeque;
public class LinkedBlockingDequeExample {
    public static void main(String[] args) throws InterruptedException {
        LinkedBlockingDeque<Integer> deque = new LinkedBlockingDeque<>(5);
         
        // Adding elements to the deque
        deque.offerFirst(1);
        deque.offerLast(2);
        deque.offerFirst(3);
        deque.offerLast(4);
         
        // Removing elements from the deque
        System.out.println(deque.pollFirst()); // Output: 3
        System.out.println(deque.pollLast()); // Output: 4
    }
}
輸出
3
4

在此示例中,我們創建一個容量為 5 的LinkedBlockingDeque,並使用 OfferFirst 和 OfferLast 方法將元素添加到雙端隊列中。然後,我們使用 pollFirst 和 pollLast 方法從雙端隊列中刪除元素,並將結果打印到控製台。

使用 LinkedBlockingDeque 的優點:

  1. 線程安全:LinkedBlockingDeque 類是線程安全的,這意味著多個線程可以同時訪問它,而不會遇到數據損壞。
  2. 高效:LinkedBlockingDeque 類為從雙端隊列兩端插入和刪除元素提供了恒定時間性能,使其成為需要執行大量添加和刪除操作的場景的不錯選擇。
  3. 可擴展:LinkedBlockingDeque 類使用鏈表來存儲其元素,這使其具有可擴展性,適合在高性能和並發應用程序中使用。
  4. 高並發:LinkedBlockingDeque類使用lock-free算法,這意味著多個線程可以同時訪問雙端隊列,無需加鎖,適合高並發應用。
  5. 阻塞行為:LinkedBlockingDeque 類提供插入和刪除元素的阻塞行為,這意味著嘗試將元素插入完整雙端隊列或從空雙端隊列中刪除元素的線程將被阻塞,直到空間可用或元素可用。

使用 LinkedBlockingDeque 的缺點:

  1. 更多內存開銷:LinkedBlockingDeque 類使用鏈表來存儲其元素,這意味著它比基於數組的實現(例如 ArrayDeque 類)需要更多內存開銷。
  2. 容量有限:LinkedBlockingDeque類的容量有限,可以在創建雙端隊列時指定。如果您嘗試將元素插入完整的雙端隊列,線程將被阻塞,直到空間可用。

參考書:

Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowbeer、David Holmes 和 Doug Lea 撰寫的《Java 並發實踐》是 Java 並發編程的綜合指南

LinkedBlockingDeque的層次結構

Hierarchy of LinkedBlockingDeque in Java

它實現了可串行化,可迭代<E>,集合<E>,阻塞雙端隊列<E>,BlockingQueue,雙端隊列<E>,Queue接口和擴展AbstractQueueAbstractCollection類。
聲明:

public class LinkedBlockingDeque<E> extends AbstractQueue<E> implements BlockingDeque<E>, Serializable 
 

這裏,E是集合中存儲的元素的類型。

Java 中的構造函數LinkedBlockingDeque

為了創建 LinkedBlockingDeque 的實例,我們需要從 java.util.concurrent 包中導入它。

1.LinkedBlockingDeque():該構造函數用於構造一個空雙端隊列。在本例中,容量設置為 Integer.MAX_VALUE。

LinkedBlockingDeque<E> lbd = new LinkedBlockingDeque<E>();

2. LinkedBlockingDeque(intcapacity):此構造函數創建具有給定(固定)容量的LinkedBlockingDeque。

LinkedBlockingDeque<E> lbd = new LinkedBlockingDeque<E>(int capacity);

3. LinkedBlockingDeque(Collection<E> c):該構造函數用於構造一個雙端隊列,並將 Collection 的元素作為參數傳遞。

LinkedBlockingDeque<E> lbd = new LinkedBlockingDeque<E>(Collection<? extends E> c);

下麵是一個示例程序,用於說明 Java 中的LinkedBlockingDeque:

示例 1:

Java


// Java Program Demonstrate LinkedBlockingDeque
import java.util.concurrent.LinkedBlockingDeque;
import java.util.*;
public class LinkedBlockingDequeDemo {
    public static void main(String[] args)
        throws InterruptedException
    {
        // create object of LinkedBlockingDeque
        // using LinkedBlockingDeque() constructor
        LinkedBlockingDeque<Integer> LBD
            = new LinkedBlockingDeque<Integer>();
        // Add numbers to end of LinkedBlockingDeque
        LBD.add(7855642);
        LBD.add(35658786);
        LBD.add(5278367);
        LBD.add(74381793);
        // print Deque
        System.out.println("Linked Blocking Deque1: "
                           + LBD);
        System.out.println("Size of Linked Blocking Deque1: "
                           + LBD.size());
        // create object of LinkedBlockingDeque
        // using LinkedBlockingDeque(int capacity) constructor
        LinkedBlockingDeque<Integer> LBD1
            = new LinkedBlockingDeque<Integer>(3);
        // Add numbers to end of LinkedBlockingDeque
        LBD1.add(7855642);
        LBD1.add(35658786);
        LBD1.add(5278367);
        try {
            // adding the 4th element
            // will throw exception for Deque full
            LBD1.add(74381793);
        }
        catch (Exception e) {
            System.out.println("Exception: " + e);
        }
        // print Deque
        System.out.println("Linked Blocking Deque2: "
                           + LBD1);
        System.out.println("Size of Linked Blocking Deque2: "
                           + LBD1.size());
        // create object of LinkedBlockingDeque
        // using LinkedBlockingDeque(Collection c) constructor
        LinkedBlockingDeque<Integer> LBD2
            = new LinkedBlockingDeque<Integer>(LBD1);
        // print Deque
        System.out.println("Linked Blocking Deque3: "
                           + LBD2);
    }
}
輸出
Linked Blocking Deque1: [7855642, 35658786, 5278367, 74381793]
Size of Linked Blocking Deque1: 4
Exception: java.lang.IllegalStateException: Deque full
Linked Blocking Deque2: [7855642, 35658786, 5278367]
Size of Linked Blocking Deque2: 3
Linked Blocking Deque3: [7855642, 35658786, 5278367]

示例 2:

Java


// Java code to illustrate methods of LinkedBlockingDeque
import java.util.concurrent.LinkedBlockingDeque;
import java.util.*;
public class LinkedBlockingDequeDemo {
    public static void main(String[] args)
        throws InterruptedException
    {
        // create object of LinkedBlockingDeque
        LinkedBlockingDeque<Integer> LBD
            = new LinkedBlockingDeque<Integer>();
        // Add numbers to end of LinkedBlockingDeque
        // using add() method
        LBD.add(7855642);
        LBD.add(35658786);
        LBD.add(5278367);
        LBD.add(74381793);
        // prints the Deque
        System.out.println("Linked Blocking Deque: "
                           + LBD);
        // prints the size of Deque after removal
        // using size() method
        System.out.println("Size of Linked Blocking Deque: "
                           + LBD.size());
        // removes the front element and prints it
        // using removeFirst() method
        System.out.println("First element: "
                           + LBD.removeFirst());
        // prints the Deque
        System.out.println("Linked Blocking Deque: "
                           + LBD);
        // prints the size of Deque after removal
        // using size() method
        System.out.println("Size of Linked Blocking Deque: "
                           + LBD.size());
        // Add numbers to end of LinkedBlockingDeque
        // using offer() method
        LBD.offer(20);
        // prints the Deque
        System.out.println("Linked Blocking Deque: "
                           + LBD);
        // prints the size of Deque after removal
        // using size() method
        System.out.println("Size of Linked Blocking Deque: "
                           + LBD.size());
    }
}
輸出
Linked Blocking Deque: [7855642, 35658786, 5278367, 74381793]
Size of Linked Blocking Deque: 4
First element: 7855642
Linked Blocking Deque: [35658786, 5278367, 74381793]
Size of Linked Blocking Deque: 3
Linked Blocking Deque: [35658786, 5278367, 74381793, 20]
Size of Linked Blocking Deque: 4

Basic Operations

1. 添加元素

LinkedBlockingDeque提供了多種方法在兩端添加或插入元素。它們是add(E e)addAll(Collection c)addFirst(E e)addLast(E e)等。

Java


// Java Program Demonstrate adding
// elements to LinkedBlockingDeque
import java.util.concurrent.LinkedBlockingDeque;
import java.util.*;
public class AddingElementsExample {
    public static void main(String[] args)
        throws IllegalStateException
    {
        // create object of LinkedBlockingDeque
        LinkedBlockingDeque<Integer> lbd
            = new LinkedBlockingDeque<Integer>();
        // Add number to end of LinkedBlockingDeque
        lbd.add(7855642);
        // Add integer at the head or front
        lbd.addFirst(35658786);
        // Add integer at the tail or end
        lbd.addLast(5278367);
        // print Deque
        System.out.println("Linked Blocking Deque: " + lbd);
           
          // Create object of ArrayList collection 
        ArrayList<Integer> ArrLis 
            = new ArrayList<Integer>(); 
   
        // Add number to ArrayList 
        ArrLis.add(55); 
        ArrLis.add(66); 
        ArrLis.add(77); 
        ArrLis.add(88); 
   
        // Print ArrayList 
        System.out.println("ArrayList: " + ArrLis); 
   
        // Function addAll() adds all the elements of 
        // ArrayList to Deque 
        lbd.addAll(ArrLis); 
   
        // Print deque 
        System.out.println("Linked Blocking Deque: " + lbd); 
    }
}
輸出
Linked Blocking Deque: [35658786, 7855642, 5278367]
ArrayList: [55, 66, 77, 88]
Linked Blocking Deque: [35658786, 7855642, 5278367, 55, 66, 77, 88]

2. 刪除元素

LinkedBlockingDeque 提供了多種方法來從任一端刪除或刪除元素。它們是remove()removeFirst()removeLast()等。

Java


// Java Program Demonstrate removing
// elements of LinkedBlockingDeque
import java.util.concurrent.LinkedBlockingDeque;
import java.util.*;
public class RemovingElementsExample {
    public static void main(String[] args)
        throws InterruptedException
    {
        // create object of LinkedBlockingDeque
        LinkedBlockingDeque<Integer> lbd
            = new LinkedBlockingDeque<Integer>();
        // Add numbers to end of LinkedBlockingDeque
        lbd.add(7855642);
        lbd.add(35658786);
        lbd.add(5278367);
        lbd.add(74381793);
        lbd.add(12345566);
        // print Dequeue
        System.out.println("Linked Blocking Deque: " + lbd);
        // removes the front element
        lbd.remove();
        // print the modified deque
        System.out.println("Linked Blocking Deque: " + lbd);
        // removes the front element
        lbd.removeFirst();
        // print the modified deque
        System.out.println("Linked Blocking Deque: " + lbd);
        // removes the last element
        lbd.removeLast();
        // print the modified deque
        System.out.println("Linked Blocking Deque: " + lbd);
    }
}
輸出
Linked Blocking Deque: [7855642, 35658786, 5278367, 74381793, 12345566]
Linked Blocking Deque: [35658786, 5278367, 74381793, 12345566]
Linked Blocking Deque: [5278367, 74381793, 12345566]
Linked Blocking Deque: [5278367, 74381793]


輸出
Linked Blocking Deque: [7855642, 35658786, 5278367, 74381793, 12345566]
Linked Blocking Deque: [35658786, 5278367, 74381793, 12345566]
Linked Blocking Deque: [5278367, 74381793, 12345566]
Linked Blocking Deque: [5278367, 74381793]

3. 迭代

LinkedBlockingDeque 的 iterator() 方法以正確的順序返回此雙端隊列中元素的迭代器。元素將按從第一個(頭)到最後一個(尾)的順序返回。返回的迭代器是一個弱一致性迭代器。

Java


// Java Program Demonstrate iterating
// over LinkedBlockingDeque
import java.util.concurrent.LinkedBlockingDeque;
import java.util.*;
public class IteratingExample {
    public static void main(String[] args)
    {
        // create object of LinkedBlockingDeque
        LinkedBlockingDeque<Integer> LBD
            = new LinkedBlockingDeque<Integer>();
        // Add numbers to front of LinkedBlockingDeque
        LBD.addFirst(7855642);
        LBD.addFirst(35658786);
        LBD.addFirst(5278367);
        LBD.addFirst(74381793);
        // Call iterator() method of LinkedBlockingDeque
        Iterator iteratorVals = LBD.iterator();
        // Print elements of iterator
        // created from PriorityBlockingQueue
        System.out.println("The iterator values"
            + " of LinkedBlockingDeque are:");
        // prints the elements using an iterator
        while (iteratorVals.hasNext()) {
            System.out.println(iteratorVals.next());
        }
    }
}
輸出
The iterator values of LinkedBlockingDeque are:
74381793
5278367
35658786
7855642


輸出
The iterator values of LinkedBlockingDeque are:
74381793
5278367
35658786
7855642

LinkedBlockingDeque的方法

METHOD

DESCRIPTION

add(E e) 在此雙端隊列的末尾插入指定元素,除非它違反容量限製。
addAll(集合 <? 擴展 E> c) 將指定集合中的所有元素按照指定集合的迭代器返回的順序附加到此雙端隊列的末尾。
addFirst(E e) 如果可以在不違反容量限製的情況下立即執行此操作,則在此雙端隊列的前麵插入指定的元素,如果當前沒有可用空間,則拋出 IllegalStateException。
addLast(E e) 如果可以在不違反容量限製的情況下立即執行此操作,則在此雙端隊列的末尾插入指定的元素,如果當前沒有可用空間,則拋出 IllegalStateException。
LinkedBlockingDeque clear() 以原子方式刪除此雙端隊列中的所有元素。
contains(Object o) 如果此雙端隊列包含指定元素,則返回 true。
descendingIterator() 按相反順序返回此雙端隊列中元素的迭代器。
dropTo(Collection<? super E> c) 從此隊列中刪除所有可用元素並將它們添加到給定集合中。
dropTo(Collection<? super E> c, int maxElements) 從此隊列中刪除最多給定數量的可用元素並將它們添加到給定的集合中。
element() 檢索但不刪除此雙端隊列所表示的隊列的頭部。
LinkedBlockingDeque forEach() 對 Iterable 的每個元素執行給定的操作,直到處理完所有元素或該操作引發異常。
getFirst() 檢索但不刪除此雙端隊列的第一個元素。
getLast() 檢索但不刪除此雙端隊列的最後一個元素。
iterator() 以正確的順序返回此雙端隊列中元素的迭代器。
LinkedBlockingDeque offer() 如果可以在不違反容量限製的情況下立即執行此操作,則將指定元素插入此雙端隊列表示的隊列中(換句話說,在此雙端隊列的尾部),成功時返回 true,如果當前沒有可用空間,則返回 false。
LinkedBlockingDeque offer() 將指定的元素插入此雙端隊列表示的隊列中(換句話說,在此雙端隊列的尾部),如果需要空間可用,則等待指定的等待時間。
offerFirst(E e) 如果可以在不違反容量限製的情況下立即執行此操作,則在此雙端隊列的前麵插入指定的元素,成功時返回 true,如果當前沒有可用空間則返回 false。
offerFirst(E e, long timeout, TimeUnit unit) 在此雙端隊列的前麵插入指定的元素,如果需要空間可用,則等待指定的等待時間。
offerLast(E e) 如果可以在不違反容量限製的情況下立即執行此操作,則在此雙端隊列的末尾插入指定元素,成功時返回 true,如果當前沒有可用空間則返回 false。
offerLast(E e, long timeout, TimeUnit unit) 在此雙端隊列的末尾插入指定的元素,如果需要空間可用,則等待指定的等待時間。
pop() 從此雙端隊列表示的堆棧中彈出一個元素。
push(E e) 如果可以立即執行此操作而不違反容量限製,則將元素推送到此雙端隊列表示的堆棧上(換句話說,在此雙端隊列的頭部),如果當前沒有可用空間,則拋出 IllegalStateException。
LinkedBlockingDeque put() 將指定元素插入此雙端隊列表示的隊列中(換句話說,在此雙端隊列的尾部),必要時等待空間可用。
putFirst(E e) 在此雙端隊列的前麵插入指定的元素,必要時等待空間可用。
LinkedBlockingDeque putLast() 在此雙端隊列的末尾插入指定的元素,必要時等待空間可用。
remainingCapacity() 返回此雙端隊列理想情況下(在沒有內存或資源限製的情況下)可以無阻塞地接受的附加元素的數量。
LinkedBlockingDeque remove() 檢索並刪除此雙端隊列所表示的隊列的頭部。
remove(Object o) 從此雙端隊列中刪除第一次出現的指定元素。
移除全部(集合<?> c) 刪除指定集合中也包含的所有該集合的元素(可選操作)。
LinkedBlockingDeque removeFirst() 檢索並刪除此雙端隊列的第一個元素。
removeIf(Predicate<? super E> 過濾器) 刪除此集合中滿足給定謂詞的所有元素。
removeLast() 檢索並刪除此雙端隊列的最後一個元素。
keepAll(集合<?> c) 僅保留此集合中包含在指定集合中的元素(可選操作)。
size() 返回此雙端隊列中的元素數量。
spliterator() 返回此雙端隊列中元素的Spliterator
toArray() 返回一個數組,其中包含此雙端隊列中的所有元素,按正確的順序(從第一個元素到最後一個元素)。
toArray(T[] a) 返回一個數組,其中包含此雙端隊列中的所有元素(按正確順序);返回數組的運行時類型是指定數組的運行時類型。

類 java.util.AbstractCollection 中聲明的方法

METHOD

DESCRIPTION

AbstractCollection containsAll() 如果此集合包含指定集合中的所有元素,則返回 true。
AbstractCollection isEmpty() 如果此集合不包含任何元素,則返回 true。
AbstractCollection toString() 返回此集合的字符串表示形式。

接口 java.util.concurrent.BlockingDeque 中聲明的方法

METHOD

DESCRIPTION

BlockingDeque peek() 檢索但不刪除此雙端隊列表示的隊列頭(換句話說,此雙端隊列的第一個元素),或者如果此雙端隊列為空,則返回 null。
BlockingDeque poll() 檢索並刪除此雙端隊列所表示的隊列的頭部(換句話說,此雙端隊列的第一個元素),或者如果此雙端隊列為空,則返回 null。
BlockingDeque poll() 檢索並刪除此雙端隊列所表示的隊列的頭部(換句話說,此雙端隊列的第一個元素),如果需要元素變得可用,則等待指定的等待時間。
BlockingDeque pollFirst() 檢索並刪除此雙端隊列的第一個元素,如果需要元素變得可用,則等待指定的等待時間。
BlockingDeque pollLast() 檢索並刪除此雙端隊列的最後一個元素,如果需要元素變得可用,則等待指定的等待時間。
BlockingDeque removeFirstOccurrence() 從此雙端隊列中刪除第一次出現的指定元素。
BlockingDeque removeLastOccurrence() 從此雙端隊列中刪除最後一次出現的指定元素。
BlockingDeque take() 檢索並刪除此雙端隊列表示的隊列頭(換句話說,此雙端隊列的第一個元素),如有必要,則等待直到有元素可用。
BlockingDeque takeFirst() 檢索並刪除此雙端隊列的第一個元素,如有必要,則等待直到元素可用。
BlockingDeque takeLast() 檢索並刪除此雙端隊列的最後一個元素,如有必要,則等待直到元素可用。

接口 java.util.Collection 中聲明的方法

METHOD

DESCRIPTION

containsAll(集合<?> c) 如果此集合包含指定集合中的所有元素,則返回 true。
equals(Object o) 比較指定對象與此集合是否相等。
hashCode() 返回此集合的哈希碼值。
isEmpty() 如果此集合不包含任何元素,則返回 true。
parallelStream() 返回一個可能並行的 Stream 並以此集合作為其源。
stream() 返回以此集合作為源的順序 Stream。
toArray(IntFunction<T[]> 生成器) 返回一個包含此集合中所有元素的數組,使用提供的生成器函數分配返回的數組。

接口 java.util.Deque 中聲明的方法

METHOD

DESCRIPTION

peekFirst() 檢索但不刪除此雙端隊列的第一個元素,或者如果此雙端隊列為空,則返回 null。
peekLast() 檢索但不刪除此雙端隊列的最後一個元素,或者如果此雙端隊列為空,則返回 null。
pollFirst() 檢索並刪除此雙端隊列的第一個元素,如果此雙端隊列為空,則返回 null。
pollLast() 檢索並刪除此雙端隊列的最後一個元素,或者如果此雙端隊列為空,則返回 null。

參考:https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/LinkedBlockingDeque.html



相關用法


注:本文由純淨天空篩選整理自RishabhPrabhu大神的英文原創作品 LinkedBlockingDeque in Java with Examples。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。