📜  Java中的BlockingQueue接口(1)

📅  最后修改于: 2023-12-03 15:16:28.564000             🧑  作者: Mango

Java中的BlockingQueue接口

BlockingQueue接口是Java 5中引入的一个新的接口,它是Java集合框架中的一部分,用于实现生产者-消费者模式,是在多线程编程中非常有用的工具。

概述

BlockingQueue是一个阻塞队列,它支持两个附加操作:阻塞插入和阻塞删除。如果队列已满,插入操作将被阻塞,直到队列中有空间。如果队列已空,删除操作将被阻塞,直到队列中有可用项。

BlockingQueue有多种实现方式:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、DelayQueue、SynchronousQueue等。

常用方法
1. put()和take()

BlockingQueue接口的put()和take()方法分别用于将元素添加到队列尾部和从队列头部获取元素。如果队列已满,put()方法会一直阻塞直到队列不满,该方法的调用方式如下:

BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
queue.put("hello");

如果队列为空,take()方法会一直阻塞直到队列不空,该方法的调用方式如下:

BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
String str = queue.take();
2. offer()和poll()

BlockingQueue接口的offer()和poll()方法分别用于将元素添加到队列尾部和从队列头部获取元素,与put()和take()方法不同的是,它们不会阻塞,而是通过返回值来表示操作成功或失败。

offer()方法的调用方式如下:

BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
boolean res = queue.offer("hello");

poll()方法的调用方式如下:

BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
String str = queue.poll();
3. remainingCapacity()

BlockingQueue接口的remainingCapacity()方法用于获取队列中可用的剩余容量。该方法的调用方式如下:

BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
int capacity = queue.remainingCapacity();
4. drainTo()

BlockingQueue接口中的drainTo()方法用于一次性从队列中移除多个元素,并将它们添加到给定的Collection中。该方法的调用方式如下:

BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
List<String> list = new ArrayList<>();
queue.drainTo(list);
示例

以下是一个生产者-消费者模型的示例。其中Producer线程往队列中不断添加字符串,Consumer线程不断从队列中取出字符串并输出:

public class ProducerConsumer {
    public static void main(String[] args) {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
        Runnable producer = () -> {
            while (true) {
                try {
                    queue.put("hello");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Runnable consumer = () -> {
            while (true) {
                try {
                    String str = queue.take();
                    System.out.println(str);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(producer).start();
        new Thread(consumer).start();
    }
}
总结

BlockingQueue接口提供了一个非常方便的多线程编程工具,它可以有效地实现生产者-消费者模型。在使用时,需要根据具体情况选择不同的实现方式,并合理地使用常用方法。