Java LinkedBlockingQueue

LinkedBlockingQueue 类是 Java 集合框架 的一部分,它提供了基于 链表 的阻塞队列实现。

它实现了 Java BlockingQueue 接口

ArrayBlockingQueue implements the BlockingQueue interface in Java.

创建 LinkedBlockingQueue

为了创建链表阻塞队列,我们必须导入 java.util.concurrent.LinkedBlockingQueue 包。

下面是在 Java 中创建链表阻塞队列的方法

1. 无初始容量

LinkedBlockingQueue<Type> animal = new LinkedBlockingQueue<>();

此时,默认的初始容量为 231-1。

2. 带有初始容量

LinkedBlockingQueue<Type> animal = new LinkedBlockingQueue<>(int capacity);

这里,

  • Type - 链表阻塞队列的类型
  • capacity - 链表阻塞队列的大小

例如,

// Creating String type LinkedBlockingQueue with size 5
LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

// Creating Integer type LinkedBlockingQueue with size 5
LinkedBlockingQueue<Integer> age = new LinkedBlockingQueue<>(5);

注意: 提供链表的尺寸不是必需的。


LinkedBlockingQueue 的方法

LinkedBlockingQueue 类提供了 BlockingQueue 接口 中所有方法的实现。

这些方法用于向链表阻塞队列中插入、访问和删除元素。

此外,我们还将学习 put()take() 方法,它们支持链表阻塞队列中的阻塞操作。

这两个方法使链表阻塞队列区别于其他典型的队列。


插入元素

  • add() - 向链表阻塞队列中插入指定的元素。如果队列已满,它会抛出 异常
  • offer() - 向链表阻塞队列中插入指定的元素。如果队列已满,它返回 false

例如,

import java.util.concurrent.LinkedBlockingQueue;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

        // Using add()
        animals.add("Dog");
        animals.add("Cat");

        // Using offer()
        animals.offer("Horse");
        System.out.println("LinkedBlockingQueue: " + animals);
    }
}

输出

LinkedBlockingQueue: [Dog, Cat, Horse]

访问元素

  • peek() - 返回链表阻塞队列前端的元素。如果队列为空,它返回 null
  • iterator() - 返回一个 迭代器 对象,用于按顺序访问链表阻塞队列中的元素。如果队列为空,它会抛出异常。我们必须导入 java.util.Iterator 包才能使用它。

例如,

import java.util.concurrent.LinkedBlockingQueue;
import java.util.Iterator;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

        // Add elements
        animals.add("Dog");
        animals.add("Cat");
        animals.add("Horse");
        System.out.println("LinkedBlockingQueue: " + animals);

        // Using peek()
        String element = animals.peek();
        System.out.println("Accessed Element: " + element);

        // Using iterator()
        Iterator<String> iterate = animals.iterator();
        System.out.print("LinkedBlockingQueue Elements: ");

        while(iterate.hasNext()) {
            System.out.print(iterate.next());
            System.out.print(", ");
        }
    }
}

输出

LinkedBlockingQueue: [Dog, Cat, Horse]
Accessed Element: Dog
LinkedBlockingQueue Elements: Dog, Cat, Horse,

移除元素

  • remove() - 返回并从链表阻塞队列中移除指定的元素。如果队列为空,它会抛出异常。
  • poll() - 返回并从链表阻塞队列中移除指定的元素。如果队列为空,它返回 null
  • clear() - 移除链表阻塞队列中的所有元素。

例如,

import java.util.concurrent.LinkedBlockingQueue;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

        animals.add("Dog");
        animals.add("Cat");
        animals.add("Horse");
        System.out.println("LinkedBlockingQueue " + animals);

        // Using remove()
        String element1 = animals.remove();
        System.out.println("Removed Element:");
        System.out.println("Using remove(): " + element1);

        // Using poll()
        String element2 = animals.poll();
        System.out.println("Using poll(): " + element2);

        // Using clear()
        animals.clear();
        System.out.println("Updated LinkedBlockingQueue " + animals);
    }
}

输出

LinkedBlockingQueue: [Dog, Cat, Horse]
Removed Elements:
Using remove(): Dog
Using poll(): Cat
Updated LinkedBlockingQueue: []

put() 和 take() 方法

在多线程进程中,我们可以使用 put()take() 来阻塞一个线程的操作,以使其与另一个线程同步。这些方法将等待直到它们能够成功执行。


put() 方法

要将指定的元素插入到链表阻塞队列的末尾,我们使用 put() 方法。

如果链表阻塞队列已满,它将等待直到链表阻塞队列中有空间来插入元素。

例如,

import java.util.concurrent.LinkedBlockingQueue;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

       try {
        // Add elements to animals
           animals.put("Dog");
           animals.put("Cat");
           System.out.println("LinkedBlockingQueue: " + animals);
        }
        catch(Exception e) {
            System.out.println(e);
        }
    }
}

输出

LinkedBlockingQueue: [Dog, Cat]

在这里,如果 put() 方法在等待时被中断,它可能会抛出 InterruptedException。因此,我们必须将其包含在 try..catch 块 中。


take() 方法

要返回并从链表阻塞队列的前端移除一个元素,我们可以使用 take() 方法。

如果链表阻塞队列为空,它将等待直到链表阻塞队列中有元素可供删除。

例如,

import java.util.concurrent.LinkedBlockingQueue;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

       try {
           //Add elements to animals
           animals.put("Dog");
           animals.put("Cat");
           System.out.println("LinkedBlockingQueue: " + animals);

           // Remove an element
           String element = animals.take();
           System.out.println("Removed Element: " + element);
           System.out.println("New LinkedBlockingQueue: " + animals);
        }
        catch(Exception e) {
            System.out.println(e);
        }
    }
}

输出

LinkedBlockingQueue: [Dog, Cat]
Removed Element: Dog
New LinkedBlockingQueue: [Cat]

在这里,如果 take() 方法在等待时被中断,它会抛出 InterrupedException。因此,我们必须将其包含在 try...catch 块中。


其他方法

方法 描述
contains(element) 在链表阻塞队列中搜索指定的元素。如果找到该元素,则返回 true,否则返回 false
size() 返回链表阻塞队列的长度。
toArray() 将链表阻塞队列转换为数组并返回该数组。
toString() 将链表阻塞队列转换为字符串

为什么使用 LinkedBlockingQueue?

LinkedBlockingQueue 使用链表作为其内部存储。

它被认为是一个线程安全的集合。因此,它通常用于多线程应用程序。

假设一个线程正在向队列中插入元素,而另一个线程正在从队列中移除元素。

现在,如果第一个线程比第二个线程慢,那么链表阻塞队列可以使第二个线程等待,直到第一个线程完成其操作。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战