当前位置:首页 > Java

java队列如何阻塞

2026-03-22 12:31:11Java

阻塞队列的实现方式

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

关键方法:

  • 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手动实现阻塞逻辑:

java队列如何阻塞

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文件

运行Java文件的方法 确保已安装Java Development Kit (JDK),可通过命令行输入java -version和javac -version验证安装。 编写Java代码并保存为.…

如何安装java环境

如何安装java环境

下载JDK安装包 访问Oracle官方网站或OpenJDK项目页面,选择适合操作系统的JDK版本(如Windows、macOS或Linux)。确保下载与系统架构匹配的版本(32位或64位)。 运行安…

java前景如何

java前景如何

Java 当前的市场需求 Java 在企业级开发、大数据、云计算等领域仍占据重要地位。许多大型企业(如银行、电商平台)依赖 Java 构建后端系统。招聘平台数据显示,Java 开发岗位数量稳定,尤其在…

如何搭建java环境

如何搭建java环境

下载JDK 访问Oracle官网或OpenJDK官网下载适合操作系统的JDK安装包。推荐选择长期支持版本(如JDK 17或JDK 21)。 安装JDK 运行下载的安装程序,按照向导完成安装。注意…

如何导入java项目

如何导入java项目

导入Java项目的方法 使用IDE导入(如IntelliJ IDEA或Eclipse) 打开IDE后选择导入现有项目,导航至项目根目录(包含pom.xml或build.gradle的文件位置)。IDE…

如何系统的学习java

如何系统的学习java

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