手动实现堵塞队列

在并发编程中,阻塞队列是一种常见的数据结构,它支持多线程间安全的数据交换。本文将介绍如何使用 Java 中的 waitnotify 方法来实现一个简单的阻塞队列。

目录

队列结构与设计

类成员

插入元素方法 queueInsert()

移除元素方法 queueRemove()

主程序及线程运行

实现思路解析

总结


队列结构与设计

我们将实现一个基于 LinkedList 的简单阻塞队列,具有固定的长度限制。队列中的元素类型为整数。

类成员

private static Queue<Integer> queue = new LinkedList<>(); // 使用 LinkedList 作为队列实现
private static final int LENGTH = 5; // 队列长度限制
private static Random random = new Random(); // 用于生成随机数
private static Object lock = new Object(); // 用于同步的锁对象

插入元素方法 queueInsert()

public static void queueInsert() {
    synchronized (lock) {
        while (queue.size() >= LENGTH) {
            try {
                System.out.println("队列已满,等待空间");
                lock.wait(); // 队列已满,等待空间释放
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 生成随机数作为新元素
        int index = random.nextInt(10);
        queue.offer(index); // 将新元素添加到队列尾部
        System.out.println("队列添加数据:" + index);
        lock.notifyAll(); // 唤醒所有等待线程
    }
}

移除元素方法 queueRemove()

public static void queueRemove() {
    synchronized (lock) {
        while (queue.isEmpty()) {
            try {
                System.out.println("队列为空,等待数据");
                lock.wait(); // 队列为空,等待数据可用
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        int index = queue.remove(); // 移除队首元素
        System.out.println(index + "被移除");
        lock.notifyAll(); // 唤醒所有等待线程
    }
}

主程序及线程运行

main 方法中启动两个线程,一个负责插入元素,一个负责移除元素:

public static void main(String[] args) {
    Thread threadInsert = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                queueInsert();
                try {
                    Thread.sleep(random.nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    Thread threadRemove = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                queueRemove();
                try {
                    Thread.sleep(random.nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    threadInsert.start();
    threadRemove.start();
}

实现思路解析

  1. 同步机制: 使用 synchronized 关键字和一个共享的 lock 对象来保证线程安全。
  2. 等待和唤醒: 在队列已满或为空时,使用 lock.wait() 让当前线程进入等待状态,直到被 lock.notifyAll() 唤醒。
  3. 线程操作: queueInsert() 负责向队列中添加元素,当队列已满时等待空闲空间;queueRemove() 负责从队列中移除元素,当队列为空时等待数据可用。
  4. 随机等待时间: 为了模拟真实场景,每个操作都会随机等待一段时间。

总结

通过以上实现,我们成功创建了一个简单的阻塞队列,并使用 waitnotify 方法实现了线程间的协作。这种设计能有效地避免常见的并发问题,如数据竞争和死锁,提升了程序的可靠性和稳定性。

在实际应用中,Java 的并发包 java.util.concurrent 提供了更高级的并发数据结构,如 BlockingQueue,它们已经封装了底层的并发控制机制,能够更方便地处理多线程情况下的数据交换操作。

相关推荐

  1. 手动实现堵塞队列

    2024-07-18 23:56:02       26 阅读
  2. js手动实现unshift

    2024-07-18 23:56:02       33 阅读
  3. redis 实现队列

    2024-07-18 23:56:02       61 阅读
  4. kafka实现延迟队列

    2024-07-18 23:56:02       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 23:56:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 23:56:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 23:56:02       58 阅读
  4. Python语言-面向对象

    2024-07-18 23:56:02       69 阅读

热门阅读

  1. pytorch中numel()函数用于获取张量中元素数目

    2024-07-18 23:56:02       20 阅读
  2. CSS浮动

    CSS浮动

    2024-07-18 23:56:02      20 阅读
  3. 什么是虚拟DOM?什么是diff算法?

    2024-07-18 23:56:02       20 阅读
  4. 什么是CAP理论?

    2024-07-18 23:56:02       20 阅读
  5. Hive修改表中的某个值

    2024-07-18 23:56:02       23 阅读
  6. HTTP请求五类状态码详细介绍,以及部分处理思路

    2024-07-18 23:56:02       24 阅读
  7. SQL FOREIGN KEY

    2024-07-18 23:56:02       19 阅读