当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。