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


Java ConcurrentLinkedDeque用法及代码示例


ConcurrentLinkedDequeJava 中的类是Java集合框架并实施采集接口AbstractCollection 类。它属于java.util.concurrent包。它用于实现双端队列借助LinkedList同时。

ConcurrentLinkedDeque的特点

  • 迭代器和分裂器是弱一致的。
  • 并发插入、删除和访问操作可以跨多个线程安全地执行。
  • 它不允许空元素。
  • size()方法不是在恒定时间内实现的。由于这些双端队列的异步性质,确定当前元素数量需要遍历元素。

Java 中的 ConcurrentLinkedDeque 类是 Deque 接口的线程安全实现,它使用链表来存储其元素。 ConcurrentLinkedDeque 类提供了 ArrayDeque 类的可扩展且高性能的替代方案,特别是在多个线程同时访问双端队列的情况下。 ConcurrentLinkedDeque 类提供了从双端队列两端插入和删除元素的方法,以及从双端队列的头部和尾部检索元素的方法,使其成为需要执行大量添加和删除操作的场景的不错选择。

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

Java


import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.Deque;
public class Example {
  public static void main(String[] args) {
    Deque<Integer> deque = new ConcurrentLinkedDeque<>();
    deque.addFirst(1);
    deque.addLast(2);
    int first = deque.pollFirst();
    int last = deque.pollLast();
    System.out.println("First: " + first + ", Last: " + last);
  }
}
输出
First: 1, Last: 2

使用ConcurrentLinkedDeque的优点:

  1. 线程安全:ConcurrentLinkedDeque 类是线程安全的,这意味着多个线程可以同时访问它,而不会遇到数据损坏。
  2. 高效:ConcurrentLinkedDeque 类为从双端队列两端插入和删除元素提供了恒定时间性能,使其成为需要执行大量添加和删除操作的场景的不错选择。
  3. 可扩展:ConcurrentLinkedDeque 类使用链表来存储其元素,这使其具有可扩展性,适合在高性能和并发应用程序中使用。
  4. 高并发:ConcurrentLinkedDeque类使用lock-free算法,这意味着多个线程可以同时访问双端队列,无需加锁,适合高并发应用。

使用ConcurrentLinkedDeque的缺点:

  1. 更多内存开销:ConcurrentLinkedDeque 类使用链表来存储其元素,这意味着它比基于数组的实现(例如 ArrayDeque 类)需要更多内存开销。
  2. 容量有限:ConcurrentLinkedDeque 类没有容量限制,但它仍然需要内存来存储其元素,这意味着当旧的ConcurrentLinkedDeque 消耗过多内存时,您可能需要创建一个新的ConcurrentLinkedDeque。

类层次结构:

ConcurrentLinkedDeque in Java

声明:

public abstract class ConcurrentLinkedDeque<E>
   extends AbstractCollection<E>
      implements Deque<E>, Serializable

Here, E is the type of elements maintained by this collection.

它实现了 Serialized、Iterable、CollectionDeque<E>Queue<E> 接口。

ConcurrentLinkedDeque 的构造函数:

1.ConcurrentLinkedDeque():该构造函数用于构造一个空双端队列。

ConcurrentLinkedDeque<E> cld = new ConcurrentLinkedDeque<E>();

2. ConcurrentLinkedDeque(Collection<E> c):该构造函数用于构造一个双端队列,并将 Collection 的元素作为参数传递。

ConcurrentLinkedDeque<E> cld = new ConcurrentLinkedDeque<E>(Collection<E> c);

下面是用Java来说明ConcurrentLinkedDeque的示例程序:

Java


// Java Program to demonstrate ConcurrentLinkedDeque
import java.util.concurrent.*;
class ConcurrentLinkedDequeDemo {
    public static void main(String[] args)
    {
        // Create a ConcurrentLinkedDeque
        // using ConcurrentLinkedDeque() 
        // constructor
        ConcurrentLinkedDeque<Integer>
            cld = new ConcurrentLinkedDeque<Integer>();
         
          // add element to the front
          // using addFirst() method
        cld.addFirst(12);
        cld.addFirst(70);
        cld.addFirst(1009);
        cld.addFirst(475);
        // Displaying the existing ConcurrentLinkedDeque
        System.out.println("ConcurrentLinkedDeque: "
                           + cld);
        // Create a ConcurrentLinkedDeque
        // using ConcurrentLinkedDeque(Collection c) 
        // constructor
        ConcurrentLinkedDeque<Integer>
            cld1 = new ConcurrentLinkedDeque<Integer>(cld);
        // Displaying the existing ConcurrentLinkedDeque
        System.out.println("ConcurrentLinkedDeque1: "
                           + cld1);
    }
}
输出
ConcurrentLinkedDeque: [475, 1009, 70, 12]
ConcurrentLinkedDeque1: [475, 1009, 70, 12]

例子:

Java


// Java code to illustrate
// methods of ConcurrentLinkedDeque
import java.util.concurrent.*;
class ConcurrentLinkedDequeDemo {
    public static void main(String[] args)
    {
        // Create a ConcurrentLinkedDeque
        // using ConcurrentLinkedDeque() constructor
        ConcurrentLinkedDeque<Integer>
            cld = new ConcurrentLinkedDeque<Integer>();
         
          // add element to the front
          // using addFirst() method
        cld.addFirst(12);
        cld.addFirst(70);
        cld.addFirst(1009);
        cld.addFirst(475);
        // Displaying the existing ConcurrentLinkedDeque
        System.out.println("ConcurrentLinkedDeque: "
                           + cld);
        // Displaying the Last element
        // using getLast() method
        System.out.println("The Last element is: "
                           + cld.getLast());
        // Displaying the first element
        // using peekFirst() method
        System.out.println("First Element is: "
                           + cld.peekFirst());
        // Remove the Last element
        // using removeLast() method
        cld.removeLast();
        // Displaying the existing ConcurrentLinkedDeque
        System.out.println("ConcurrentLinkedDeque: "
                           + cld);
    }
}
输出
ConcurrentLinkedDeque: [475, 1009, 70, 12]
The Last element is: 12
First Element is: 475
ConcurrentLinkedDeque: [475, 1009, 70]

ConcurrentLinkedDeque的基本操作

1. 添加元素

要添加元素或元素集合,ConcurrentLinkedDeque 提供了 add(E e)、addAll(Collection<? extends E> c)、addFirst(E e)、addLast(E e) 等方法。下面的示例解释了这些方法。

Java


// Java Program Demonstrate adding
// elements to the ConcurrentLinkedDeque
import java.util.concurrent.*;
class AddingElements {
    public static void main(String[] args)
    {
        // create instance using ConcurrentLinkedDeque
        ConcurrentLinkedDeque<Integer> cld1
            = new ConcurrentLinkedDeque<Integer>();
        // Add element to the tail using
        // add or addLast methods
        cld1.add(12);
        cld1.add(110);
        // Add element to the head
        // using addFirst method
        cld1.addFirst(55);
        // Displaying the existing ConcurrentLinkedDeque
        System.out.println("Initial Elements in "
                           + "the LinkedDeque cld : "
                           + cld1);
        // create instance using ConcurrentLinkedDeque
        ConcurrentLinkedDeque<Integer> cld2
            = new ConcurrentLinkedDeque<Integer>();
        // Add elements of cld1 to the
        // cld2 using addAll method
        cld2.addAll(cld1);
        // Displaying the modified ConcurrentLinkedDeque
        System.out.println("Initial Elements in "
                           + "the LinkedDeque cld2: "
                           + cld2);
    }
}
输出
Initial Elements in the LinkedDeque cld : [55, 12, 110]
Initial Elements in the LinkedDeque cld2: [55, 12, 110]


输出:

Initial Elements in the LinkedDeque cld : [55, 12, 110]
Initial Elements in the LinkedDeque cld2: [55, 12, 110]

2. 删除元素

为了删除元素,ConcurrentLinkedDeque 提供了诸如 remove()、remove(Object o)、removeFirst()、removeLast() 等方法。这些方法在下面的示例中进行了解释。

Java


// Java Program to demonstrate removing
// elements of ConcurrentLinkedDeque
import java.util.concurrent.*;
class RemovingElements {
    public static void main(String[] args)
    {
        // Create a ConcurrentLinkedDeque
        // using ConcurrentLinkedDeque() constructor
        ConcurrentLinkedDeque<Integer> cld
            = new ConcurrentLinkedDeque<Integer>();
        // Add elements using add() method
        cld.add(40);
        cld.add(50);
        cld.add(60);
        cld.add(70);
        cld.add(80);
        // Displaying the existing LinkedDeque
        System.out.println(
            "Existing ConcurrentLinkedDeque: " + cld);
        // remove method removes the first
        // element of ConcurrentLinkedDeque
        // using remove() method
        System.out.println("Element removed: "
                           + cld.remove());
        // Remove 60 using remove(Object)
        System.out.println("60 removed: " + cld.remove(60));
        // Displaying the existing ConcurrentLinkedDeque
        System.out.println(
            "Modified ConcurrentLinkedDeque: " + cld);
        // Remove the first element
        cld.removeFirst();
        // Remove the Last element
        cld.removeLast();
        // Displaying the existing ConcurrentLinkedDeque
        System.out.println(
            "Modified ConcurrentLinkedDeque: " + cld);
    }
}
输出
Existing ConcurrentLinkedDeque: [40, 50, 60, 70, 80]
Element removed: 40
60 removed: true
Modified ConcurrentLinkedDeque: [50, 70, 80]
Modified ConcurrentLinkedDeque: [70]

3. 迭代元素

我们可以使用 iterator() 或 descendingIterator() 方法迭代 ConcurrentLinkedDeque。下面的代码解释了这两种方法。

Java


// Java code to illustrate iterating
// elements of ConcurrentLinkedDeque
import java.util.concurrent.*;
import java.util.*;
public class IteratingConcurrentLinkedDeque {
    public static void main(String args[])
    {
        // Creating an empty ConcurrentLinkedDeque
        ConcurrentLinkedDeque<String> deque
            = new ConcurrentLinkedDeque<String>();
        // Use add() method to add elements
        // into the ConcurrentLinkedDeque
        deque.add("Welcome");
        deque.add("To");
        deque.add("Geeks");
        deque.add("4");
        deque.add("Geeks");
        // Displaying the ConcurrentLinkedDeque
        System.out.println("ConcurrentLinkedDeque: "
                           + deque);
        // Creating an iterator
        Iterator fitr = deque.iterator();
        // Displaying the values
        // after iterating through the ConcurrentLinkedDeque
        System.out.println("The iterator values are: ");
        while (fitr.hasNext()) {
            System.out.println(fitr.next());
        }
        // Creating a desc_iterator
        Iterator ditr = deque.descendingIterator();
        // Displaying the values after iterating
        // through the ConcurrentLinkedDeque
        // in reverse order
        System.out.println("The iterator values are: ");
        while (ditr.hasNext()) {
            System.out.println(ditr.next());
        }
    }
}
输出
ConcurrentLinkedDeque: [Welcome, To, Geeks, 4, Geeks]
The iterator values are: 
Welcome
To
Geeks
4
Geeks
The iterator values are: 
Geeks
4
Geeks
To
Welcome

4. 访问元素

为了访问ConcurrentLinkedDeque的元素,它提供了getFirst()、getLast()、element()等方法。下面的示例解释了这些方法。

Java


// Java Program to Demonstrate accessing
// elements of ConcurrentLinkedDeque
import java.util.concurrent.*;
import java.util.*;
class Accessing {
    public static void main(String[] args)
    {
        // Creating an empty ConcurrentLinkedDeque
        ConcurrentLinkedDeque<String> cld
            = new ConcurrentLinkedDeque<String>();
        // Add elements into the ConcurrentLinkedDeque
        cld.add("Welcome");
        cld.add("To");
        cld.add("Geeks");
        cld.add("4");
        cld.add("Geeks");
        // Displaying the ConcurrentLinkedDeque
        System.out.println("Elements in the ConcurrentLinkedDeque: " + cld);
        // Displaying the first element
        System.out.println("The first element is: "
                           + cld.getFirst());
        // Displaying the Last element
        System.out.println("The Last element is: "
                           + cld.getLast());
        // Displaying the head of ConcurrentLinkedDeque
        System.out.println("The Head of ConcurrentLinkedDeque is: "
                           + cld.element());
    }
}
输出
Elements in the ConcurrentLinkedDeque: [Welcome, To, Geeks, 4, Geeks]
The first element is: Welcome
The Last element is: Geeks
The Head of ConcurrentLinkedDeque is: Welcome

输出:

Elements in the ConcurrentLinkedDeque: [Welcome, To, Geeks, 4, Geeks]
The first element is: Welcome
The Last element is: Geeks
The Head of ConcurrentLinkedDeque is: Welcome

ConcurrentLinkedDeque的方法

这里,E是元素的类型。

METHOD

DESCRIPTION

ConcurrentLinkedDeque add() 在此双端队列的尾部插入指定元素。
ConcurrentLinkedDeque addAll() 将指定集合中的所有元素按照指定集合的迭代器返回的顺序附加到此双端队列的末尾。
ConcurrentLinkedDeque addFirst() 在此双端队列的前面插入指定的元素。
ConcurrentLinkedDeque addLast() 在此双端队列的末尾插入指定的元素。
ConcurrentLinkedDeque clear() 从此双端队列中删除所有元素。
ConcurrentLinkedDeque contains() 如果此双端队列包含指定元素,则返回 true。
ConcurrentLinkedDeque descendingIterator() 按相反顺序返回此双端队列中元素的迭代器。
ConcurrentLinkedDeque element() 检索但不删除此双端队列表示的队列头(换句话说,此双端队列的第一个元素)。
forEach(消费者<? super E> 操作) 对 Iterable 的每个元素执行给定的操作,直到处理完所有元素或该操作引发异常。
ConcurrentLinkedDeque getFirst() 检索但不删除此双端队列的第一个元素。
ConcurrentLinkedDeque getLast() 检索但不删除此双端队列的最后一个元素。
ConcurrentLinkedDeque isEmpty() 如果此集合不包含任何元素,则返回 true。
ConcurrentLinkedDeque iterator() 以正确的顺序返回此双端队列中元素的迭代器。
ConcurrentLinkedDeque offer() 在此双端队列的尾部插入指定元素。
ConcurrentLinkedDeque offerFirst() 在此双端队列的前面插入指定的元素。
ConcurrentLinkedDeque offerLast() 在此双端队列的末尾插入指定的元素。
ConcurrentLinkedDeque pop() 从此双端队列表示的堆栈中弹出一个元素。
ConcurrentLinkedDeque push() 如果可以立即执行此操作而不违反容量限制,则将元素推送到此双端队列表示的堆栈上(换句话说,在此双端队列的头部),如果当前没有可用空间,则抛出 IllegalStateException。
ConcurrentLinkedDeque remove() 检索并删除此双端队列所表示的队列的头部(换句话说,此双端队列的第一个元素)。
ConcurrentLinkedDeque remove() 从此双端队列中删除第一次出现的指定元素。
移除全部(集合<?> c) 删除指定集合中也包含的所有该集合的元素(可选操作)。
ConcurrentLinkedDeque removeFirst() 检索并删除此双端队列的第一个元素。
ConcurrentLinkedDeque removeFirstOccurrence() 从此双端队列中删除第一次出现的指定元素。
removeIf(Predicate<? super E> 过滤器) 删除此集合中满足给定谓词的所有元素。
ConcurrentLinkedDeque removeLast() 检索并删除此双端队列的最后一个元素。
ConcurrentLinkedDeque removeLastOccurrence() 从此双端队列中删除最后一次出现的指定元素。
keepAll(集合<?> c) 仅保留此集合中包含在指定集合中的元素(可选操作)。
ConcurrentLinkedDeque size() 返回此双端队列中的元素数量。
ConcurrentLinkedDeque Spliterator() 返回此双端队列中元素的 Spliterator。
ConcurrentLinkedDeque toArray() 返回一个数组,其中包含此双端队列中的所有元素,按正确的顺序(从第一个元素到最后一个元素)。
ConcurrentLinkedDeque toArray() 返回一个数组,其中包含此双端队列中的所有元素,按正确的顺序(从第一个元素到最后一个元素);返回数组的运行时类型是指定数组的运行时类型。

类 java.util.AbstractCollection 中声明的方法

METHOD

DESCRIPTION

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

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

METHOD

DESCRIPTION

containsAll(集合<?> c) 如果此集合包含指定集合中的所有元素,则返回 true。
equals(Object o) 比较指定对象与此集合是否相等。
hashCode() 返回此集合的哈希码值。
parallelStream() 返回一个可能并行的 Stream 并以此集合作为其源。
stream() 返回以此集合作为源的顺序 Stream。
toArray(IntFunction<T[]> 生成器) 返回一个包含此集合中所有元素的数组,使用提供的生成器函数分配返回的数组。

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

METHOD

DESCRIPTION

peek() 检索但不删除此双端队列表示的队列头(换句话说,此双端队列的第一个元素),或者如果此双端队列为空,则返回 null。
peekFirst() 检索但不删除此双端队列的第一个元素,或者如果此双端队列为空,则返回 null。
peekLast() 检索但不删除此双端队列的最后一个元素,或者如果此双端队列为空,则返回 null。
poll() 检索并删除此双端队列所表示的队列的头部(换句话说,此双端队列的第一个元素),或者如果此双端队列为空,则返回 null。
pollFirst() 检索并删除此双端队列的第一个元素,如果此双端队列为空,则返回 null。
pollLast() 检索并删除此双端队列的最后一个元素,或者如果此双端队列为空,则返回 null。

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

参考书:

Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowbeer、David Holmes 和 Doug Lea 撰写的《Java 并发实践》是 Java 并发编程的综合指南,包括 ConcurrentLinkedDeque 类。本书涵盖了并发编程的基础知识,解释了如何使用java.util.concurrent包,并提供了编写正确高效代码的技巧和最佳实践。如果您想了解有关 ConcurrentLinkedDeque 类和并发编程的更多信息,这本书是一个很好的资源。



相关用法


注:本文由纯净天空筛选整理自RishabhPrabhu大神的英文原创作品 ConcurrentLinkedDeque in Java with Examples。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。