当前位置:首页 > Java

java队列如何阻塞

2026-03-22 12:31:11Java

阻塞队列的实现方式

在Java中,可以通过java.util.concurrent包提供的阻塞队列实现阻塞操作。常见的阻塞队列包括ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueueSynchronousQueue

java队列如何阻塞

关键方法:

java队列如何阻塞

  • put(E e):向队列尾部插入元素,若队列满则阻塞,直到空间可用。
  • take():移除并返回队列头部元素,若队列空则阻塞,直到有元素可用。
  • offer(E e, long timeout, TimeUnit unit):尝试插入元素,若队列满则等待指定时间后返回false
  • poll(long timeout, TimeUnit unit):尝试获取元素,若队列空则等待指定时间后返回null

示例代码

使用ArrayBlockingQueue演示阻塞操作:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueExample {
    public static void main(String[] args) {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);

        // 生产者线程
        new Thread(() -> {
            try {
                queue.put("Task 1");
                queue.put("Task 2");
                queue.put("Task 3");
                System.out.println("队列已满,尝试插入...");
                queue.put("Task 4"); // 阻塞直到队列有空位
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();

        // 消费者线程
        new Thread(() -> {
            try {
                Thread.sleep(2000); // 模拟延迟
                System.out.println("取出: " + queue.take());
                System.out.println("取出: " + queue.take());
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }
}

自定义阻塞队列

通过ReentrantLockCondition手动实现阻塞逻辑:

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class CustomBlockingQueue<T> {
    private final Queue<T> queue = new LinkedList<>();
    private final int capacity;
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notEmpty = lock.newCondition();
    private final Condition notFull = lock.newCondition();

    public CustomBlockingQueue(int capacity) {
        this.capacity = capacity;
    }

    public void put(T item) throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() == capacity) {
                notFull.await(); // 队列满时阻塞
            }
            queue.add(item);
            notEmpty.signal(); // 唤醒消费者
        } finally {
            lock.unlock();
        }
    }

    public T take() throws InterruptedException {
        lock.lock();
        try {
            while (queue.isEmpty()) {
                notEmpty.await(); // 队列空时阻塞
            }
            T item = queue.remove();
            notFull.signal(); // 唤醒生产者
            return item;
        } finally {
            lock.unlock();
        }
    }
}

适用场景

  • 生产者-消费者模型:协调生产速度和消费速度不一致的问题。
  • 线程池任务队列:如ThreadPoolExecutor使用阻塞队列管理待执行任务。
  • 资源限制:通过固定容量队列控制资源并发访问。

注意事项

  • 死锁风险:确保阻塞和唤醒逻辑配对,避免线程永久阻塞。
  • 性能权衡:根据场景选择公平锁(ReentrantLock(true))或非公平锁。

标签: 队列java
分享给朋友:

相关文章

java如何创建文件

java如何创建文件

使用 File 类创建文件 通过 File 类的 createNewFile() 方法创建文件。此方法返回布尔值,表示文件是否成功创建。 import java.io.File; import ja…

java如何配置环境变量

java如何配置环境变量

配置Java环境变量的方法 下载并安装JDK 从Oracle官网或OpenJDK下载适合操作系统的JDK安装包。运行安装程序并按照提示完成安装,记下JDK的安装路径(例如C:\Program File…

java如何获取当前时间

java如何获取当前时间

获取当前时间的方法 在Java中,可以通过多种方式获取当前时间。以下是几种常见的方法: 使用 java.util.Date Date currentDate = new Date(); Syste…

java如何导入jar包

java如何导入jar包

在Eclipse中导入JAR包 右键项目 -> 选择"Properties" -> 左侧导航选择"Java Build Path" -> 切换到"Libraries"标签 ->…

如何启用java

如何启用java

启用 Java 的方法 检查 Java 是否已安装 在命令行或终端输入 java -version,如果显示版本信息,说明 Java 已安装。若未安装,需从 Oracle 官网 或 OpenJDK 下…

如何系统的学习java

如何系统的学习java

学习Java的基础知识 Java的基础知识包括语法、数据类型、变量、运算符、控制流语句等。可以通过官方文档或入门书籍如《Java核心技术》来掌握这些内容。编写简单的程序练习基础语法,例如打印“Hell…