您的位置:首页 > 新闻 > 热点要闻 > 建筑培训网首页安全员_科技公司简介范文_东莞网站到首页排名_网站制作的费用

建筑培训网首页安全员_科技公司简介范文_东莞网站到首页排名_网站制作的费用

2024/12/31 6:43:48 来源:https://blog.csdn.net/weixin_73376914/article/details/144310514  浏览:    关键词:建筑培训网首页安全员_科技公司简介范文_东莞网站到首页排名_网站制作的费用
建筑培训网首页安全员_科技公司简介范文_东莞网站到首页排名_网站制作的费用

什么是 LinkedBlockingQueue

LinkedBlockingQueue 是 Java 中一个线程安全的 阻塞队列,它位于 java.util.concurrent 包中,底层使用 链表 实现。它被广泛用于生产者-消费者模型中,可以在多线程环境下安全地传递和管理数据。

它的核心特点是:

  • 容量限制:可以指定容量限制,防止无限制增长。
  • 线程安全:通过内置的锁机制(分离读写锁),实现线程安全。
  • 阻塞行为:在队列满时生产者线程阻塞,在队列空时消费者线程阻塞。

关键特性

  1. 基于链表实现:

    • 队列的元素通过链表节点存储,动态扩展,避免了数组实现中的容量问题。
  2. 容量控制:

    • 在构造时可以指定队列的最大容量。如果不指定,默认容量为 Integer.MAX_VALUE
  3. 线程安全:

    • 使用了两把独立的锁:putLock(用于插入操作)和 takeLock(用于移除操作)。读写操作可以并发执行,提升性能。
  4. 阻塞操作:

    • 提供阻塞的 puttake 方法:
      • put:如果队列满,当前线程会阻塞直到有空余空间。
      • take:如果队列为空,当前线程会阻塞直到队列有元素。
  5. 非阻塞操作:

    • 提供非阻塞的 offerpoll 方法,可以指定等待时间:
      • offer:尝试插入元素,若队列满则返回 false
      • poll:尝试移除元素,若队列空则返回 null

主要方法

方法名描述
put(E e)阻塞地将元素放入队列,如果队列满则等待空间。
take()阻塞地从队列取出元素,如果队列空则等待元素。
offer(E e)尝试将元素放入队列,若队列满则返回 false
offer(E e, long timeout, TimeUnit unit)尝试在指定时间内将元素放入队列,如果超时则返回 false
poll()尝试从队列取出元素,若队列空则返回 null
poll(long timeout, TimeUnit unit)尝试在指定时间内取出元素,如果超时则返回 null
peek()查看队列头部元素,但不移除,若队列为空返回 null
size()返回队列中当前的元素个数。
remainingCapacity()返回队列的剩余空间(容量 - 当前大小)。
drainTo(Collection<? super E> c)将队列中所有元素转移到另一个集合中,并清空队列。

核心原理

1. 链表结构

LinkedBlockingQueue 的底层是一个链表,其节点由静态内部类 Node 定义,每个节点存储一个元素。链表的结构如下:

2. 锁分离

LinkedBlockingQueue 使用了两个独立的锁 putLocktakeLock

  • putLock:控制插入操作。
  • takeLock:控制取出操作。
  • 锁分离允许插入和取出操作可以同时进行,提升并发性能。

此外,还使用了两个条件变量 notEmptynotFull 来实现阻塞机制:

  • notEmpty:当队列不为空时通知等待的消费者线程。
  • notFull:当队列未满时通知等待的生产者线程。
3. 容量限制
  • LinkedBlockingQueue 的容量可以在创建时指定。默认容量是 Integer.MAX_VALUE
  • 如果队列已满,生产者线程会阻塞直到有空余空间。
  • 如果队列为空,消费者线程会阻塞直到有新的元素被插入。

代码示例

基本使用
import java.util.concurrent.LinkedBlockingQueue;public class LinkedBlockingQueueExample {public static void main(String[] args) throws InterruptedException {// 创建一个容量为3的阻塞队列LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(3);// 向队列中插入元素queue.put(1);queue.put(2);queue.put(3);// 尝试插入元素(阻塞,因为队列已满)new Thread(() -> {try {System.out.println("Trying to add element...");queue.put(4);System.out.println("Element added!");} catch (InterruptedException e) {e.printStackTrace();}}).start();// 取出元素,释放空间Thread.sleep(2000);System.out.println("Taking element: " + queue.take());}
}

生产者-消费者模型
import java.util.concurrent.LinkedBlockingQueue;public class ProducerConsumer {public static void main(String[] args) {LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(5);// 生产者线程Thread producer = new Thread(() -> {try {for (int i = 1; i <= 10; i++) {System.out.println("Produced: " + i);queue.put(i); // 阻塞地放入队列}} catch (InterruptedException e) {e.printStackTrace();}});// 消费者线程Thread consumer = new Thread(() -> {try {while (true) {Integer item = queue.take(); // 阻塞地取出队列System.out.println("Consumed: " + item);}} catch (InterruptedException e) {e.printStackTrace();}});producer.start();consumer.start();}
}

应用场景

  1. 生产者-消费者模型:

    • 生产者将任务放入队列,消费者从队列中取出任务进行处理。
    • 通过阻塞机制自动协调生产和消费的速度。
  2. 多线程通信:

    • 在线程间传递数据,避免显式的同步操作。
  3. 任务调度:

    • 用于线程池的工作队列,存储需要执行的任务。

优缺点

优点
  1. 线程安全: 内置锁机制,读写操作独立。
  2. 容量控制: 可以防止内存占用过多。
  3. 阻塞功能: 自动协调生产和消费速度,无需手动管理同步。
缺点
  1. 性能较低: 相比非阻塞队列,锁机制可能带来一定的性能开销。
  2. 扩展性有限: 无法灵活调整容量限制。

LinkedBlockingQueue 底层实现
关于阻塞机制-CSDN博客

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com