阻塞队列之 LinkedBlockingQueue

发布时间 2023-12-04 14:50:44作者: 亲爱的阿道君

LinkedBlockingQueue:Java多线程编程中的阻塞队列

在Java多线程编程中,LinkedBlockingQueue 是一个非常重要的类,它提供了一种用于在生产者和消费者之间进行数据传递的机制。LinkedBlockingQueue 广泛应用于各种场景,如线程池、任务队列等。本文将详细介绍 LinkedBlockingQueue 的原理和用法,并通过代码示例进行讲解。

1. LinkedBlockingQueue简介

LinkedBlockingQueue 是Java多线程编程中的一种阻塞队列。它基于链表节点实现,支持高并发线程之间的数据传递,同时保证了数据的有序性和一致性。LinkedBlockingQueue 提供了以下几种方法:

  • put(E e):将元素插入到队列中。如果队列已满,线程将会被阻塞,直到有消费者取走元素。
  • take():从队列中取出一个元素。如果队列为空,线程将会被阻塞,直到有生产者插入元素。
  • poll():从队列中取出一个元素,如果队列为空,返回null。
  • size():返回队列中的元素个数。
  • isEmpty():判断队列是否为空。
  • isFull():判断队列是否已满。

2. LinkedBlockingQueue原理

LinkedBlockingQueue 的实现基于链表结构,每个节点包含一个元素和一个指向下一个节点的引用。当生产者向队列插入元素时,如果队列未满,直接将元素插入到链表的末尾。如果队列已满,生产者线程将被阻塞,等待消费者线程来取走元素。当消费者从队列中取出元素时,如果队列为空,消费者线程将被阻塞,等待生产者线程来插入元素。

3. LinkedBlockingQueue用法

下面通过一个简单的代码示例来讲解 LinkedBlockingQueue 的用法:

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Thread;
public class LinkedBlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
        Thread producerThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 15; i++) {
                        queue.put(i);
                        System.out.println("Produced: " + i);
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        Thread consumerThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 15; i++) {
                        int value = queue.take();
                        System.out.println("Consumed: " + value);
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        producerThread.start();
        consumerThread.start();
    }
}

在这个示例中,我们创建了一个有界队列 LinkedBlockingQueue,容量为10。然后,我们创建了两个线程:一个生产者线程和一个消费者线程。生产者线程向队列中插入元素,而消费者线程从队列中取出元素。