Java 同步阻塞队列

在多线程编程中,同步阻塞队列是一种非常重要的数据结构,它提供了一种线程安全的、有界的队列,可以用于在生产者和消费者之间传递数据。

什么是同步阻塞队列

同步阻塞队列是一种线程安全的队列,其内部实现了同步机制,可以保证多个线程对队列的访问是安全的。同时,同步阻塞队列还提供了阻塞的特性,当队列为空时,消费者线程会被阻塞,直到队列中有数据可供消费;当队列已满时,生产者线程会被阻塞,直到队列有空位可供生产。

Java 中的同步阻塞队列

Java 中提供了一个并发包(java.util.concurrent),其中包含了多种同步阻塞队列的实现。下面介绍其中三种常用的实现。

ArrayBlockingQueue

ArrayBlockingQueue 是一个基于数组的阻塞队列,它有固定的容量,在创建时需要指定队列的容量。以下是一个使用 ArrayBlockingQueue 的例子:

import java.util.concurrent.ArrayBlockingQueue;

public class ArrayBlockingQueueExample {
    public static void main(String[] args) {
        // 创建一个容量为 5 的 ArrayBlockingQueue
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5);

        // 生产者线程
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    queue.put(i); // 将数据放入队列
                    System.out.println("Produced: " + i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 消费者线程
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    int num = queue.take(); // 从队列中取出数据
                    System.out.println("Consumed: " + num);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        producer.start();
        consumer.start();
    }
}

上面的例子中,我们创建了一个容量为 5 的 ArrayBlockingQueue,并分别创建了生产者线程和消费者线程。生产者线程将数字放入队列中,消费者线程从队列中取出数字并打印。

LinkedBlockingQueue

LinkedBlockingQueue 是一个基于链表的阻塞队列,它可以有可选的容量限制。如果不指定容量或者指定为 Integer.MAX_VALUE,则队列的容量将是无限的。以下是一个使用 LinkedBlockingQueue 的例子:

import java.util.concurrent.LinkedBlockingQueue;

public class LinkedBlockingQueueExample {
    public static void main(String[] args) {
        // 创建一个无限容量的 LinkedBlockingQueue
        LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();

        // 生产者线程
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    queue.put(i); // 将数据放入队列
                    System.out.println("Produced: " + i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 消费者线程
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    int num = queue.take(); // 从队列中取出数据
                    System.out.println("Consumed: " + num);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        producer.start();
        consumer.start();
    }
}

上面的例子中,我们创建了一个无限容量的 LinkedBlockingQueue,并使用生产者线程和消费者线程对队列进行操作。

SynchronousQueue

SynchronousQueue 是一个没有存储元素的阻塞队列,它在插入和移除元素时都必须等待其他线程的操作。以下是一个使用 SynchronousQueue 的例子:

import java.util.concurrent.SynchronousQueue;

public class SynchronousQueueExample {
    public static void main(String[] args) {
        // 创建一个 Synchronous