📌  相关文章
📜  Java LinkedBlockingQueue

📅  最后修改于: 2020-09-26 14:53:50             🧑  作者: Mango

在本教程中,我们将借助示例来学习LinkedBLockingQueue类及其方法。

Java Collections框架的LinkedBlockingQueue类使用链接列表提供阻止队列的实现。

它实现了Java BlockingQueue接口。

ArrayBlockingQueue用Java实现BlockingQueue接口。


创建LinkedBlockingQueue

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

这是我们如何在Java中创建链接的阻塞队列的方法:

1.无初始容量

LinkedBlockingQueue animal = new LinkedBlockingQueue<>();

在此,默认初始容量为2 31 -1。

2.具有初始容量

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

这里,

  • Type-链接的阻塞队列的类型
  • 容量 -链接的阻塞队列的大小

例如,

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

// Creating Integer type LinkedBlockingQueue with size 5
LinkedBlockingQueue 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 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 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 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 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 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 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块中。


其他方法
Methods Descriptions
contains(element) Searches the linked blocking queue for the specified element. If the element is found, it returns true, if not it returns false.
size() Returns the length of the linked blocking queue.
toArray() Converts linked blocking queue to an array and return the array.
toString() Converts the linked blocking queue to string

为什么要使用LinkedBlockingQueue?

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

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

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

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