JUC并发编程之堵塞队列BlockingQueue

目录

11. 堵塞队列 BlockingQueue

11.1 概述

11.2 为什么需要 BlockingQueue

11.3 阻赛队列的核心方法

11.4 常见的 BlockingQueue

11.5 堵塞队列核心方法代码演示

11.6 小结


11. 堵塞队列 BlockingQueue

11.1 概述

在Concurrent 包中,BlockingQueue 很好的解决了多线程中,如何高效安全 “传输”数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建 高质量的多线程程序带来极大的便利。

阻塞队列,顾名思义,首先它是一个队列, 通过一个共享的队列,可以使得数据 由队列的一端输入,从另外一端输出。

  • 当队列是空的,从队列中获取元素的操作将会被阻塞
  • 当队列是满的,从队列中添加元素的操作将会被阻塞
  • 试图从空的队列中获取元素的线程将会被阻塞,直到其他线程往空的队列插入新的元素
  • 试图向已满的队列中添加新元素的线程将会被阻塞,直到其他线程从队列中移除一个或多个元素或者完全清空,使队列变得空闲起来以便后续新增

在多线程领域:所谓阻塞,在某些情况下会挂起线程(即阻塞),一旦条件满足,被挂起 的线程又会自动被唤起

11.2 为什么需要 BlockingQueue

  • 好处是我们不需要关心什么时候需要阻塞线程,什么时候需要唤醒线程,因为这一切 BlockingQueue 都给你一手包办了。
  • 在concurrent 包发布以前,在多线程环境下,我们每个程序员都必须去自己控制这些细 节,尤其还要兼顾效率和线程安全,而这会给我们的程序带来不小的复杂度。
  • 多线程环境中,通过队列可以很容易实现数据共享,比如经典的“生产者”和 “消费者”模型中,通过队列可以很便利地实现两者之间的数据共享。
  • 当队列中没有数据的情况下,消费者端的所有线程都会被自动阻塞(挂起), 直到有数据放入队列
  • 当队列中填满数据的情况下,生产者端的所有线程都会被自动阻塞(挂起), 直到队列中有空的位置,线程被自动唤醒

11.3 阻赛队列的核心方法

11.4 常见的 BlockingQueue

  • 由数组结构组成的有界阻塞队列     ArrayBlockingQueue(常用) 
  • 由链表结构组成的有界(但大小默认值为 integer.MAX_VALUE)阻塞队列。LinkedBlockingQueue(常用)
  • 使用优先级队列实现的延迟无界阻塞队列 DelayQueue

11.5 堵塞队列核心方法代码演示

package com.example.block_queue;
 
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
 
/**
 * 阻塞队列
 */
public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {

            //创建阻塞队列
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
 
        //---------------------------第一组------------------------------------------
            //添加数据
       /* System.out.println(queue.add("a"));
        System.out.println(queue.add("b"));
        System.out.println(queue.add("c"));
        //System.out.println(queue.add("d"));
        //检测
        //System.out.println(queue.element());
        //取出数据
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());*/
 
        //---------------------------第二组------------------------------------------
            //添加数据
       /* System.out.println(queue.offer("a"));
        System.out.println(queue.offer("b"));
        System.out.println(queue.offer("c"));
        System.out.println(queue.offer("hello"));
            //取出数据
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());*/
 
        //---------------------------第三组------------------------------------------
            //放数据
       /* queue.put("a");
        queue.put("b");
        queue.put("c");
        //queue.put("d");
            //取数据
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());*/
 
        //---------------------------第四组------------------------------------------
 
        queue.offer("a");
        queue.offer("b");
        queue.offer("c");
        queue.offer("d",3, TimeUnit.SECONDS);
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll(3,TimeUnit.SECONDS));
    
    }

}

11.6 小结

1. 在多线程领域:所谓阻塞,在某些情况下会挂起线程(即阻塞),一旦条件 满足,被挂起的线程又会自动被唤起。

2. 为什么需要 BlockingQueue?

        concurrent 包发布以前,在多线程环境下, 我们每个程序员都必须去自己控制这些细节,尤其还要兼顾效率和线程安全, 而这会给我们的程序带来不小的复杂度。使用后我们不需要关心什么时候需要 阻塞线程,什么时候需要唤醒线程,因为这一切 BlockingQueue 都给你一手包办了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值