Java中阻塞队列详解(BlockingQueue)

BlockingQueue   阻塞队列的顶层接口

        先来解释下,阻塞队列是什么,是干什么用的,阻塞通俗点讲就是堵住了进不去,在Java中阻塞是多线程运行程序,一条线程带着锁进去执行了,其他后来的线程就无法获取锁,只能等待执行,就是阻塞.阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。

阻塞队列常用的三种实现类

队列

有界性(长度)

数据结构

ArrayBlockingQueue

bounded(有界)

加锁

arrayList

LinkedBlockingQueue

optionally-bounded

加锁

linkedList

SynchronousQueue

bounded

加锁

常用实现类队列特点
  • ArrayBlockingQueue:是一个用数组实现的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序。支持公平锁和非公平锁。【注:每一个线程在获取锁的时候可能都会排队等待,如果在等待时间上,先获取锁的线程的请求一定先被满足,那么这个锁就是公平的。反之,这个锁就是不公平的。公平的获取锁,也就是当前等待时间最长的线程先获取锁】

  • LinkedBlockingQueue:一个由链表结构组成的有界队列,此队列的长度为Integer.MAX_VALUE。此队列按照先进先出的顺序进行排序。

  • SynchronousQueue: 一个不存储元素的阻塞队列,每一个put操作必须等待take操作,否则不能添加元素。支持公平锁和非公平锁。

常用方法

        boolean add(E e) 添加元素 满了抛异常

        boolean offer(E e) 添加元素 满了不抛异常 返回false

        public void put(E e) 添加元素,队列满了,则等待

        E poll(long timeout, TimeUnit unit) 在指定时间后移除元素(队列头部)

        public E take() 移除队列头部的元素

三种队列方法的代码
public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

//        BlockingQueue<Integer>  blockingQueue = new ArrayBlockingQueue<>(5);
//        BlockingQueue<Integer>  blockingQueue = new LinkedBlockingQueue<>();
        BlockingQueue<Integer>  blockingQueue = new SynchronousQueue<>();



        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    try {
                        blockingQueue.put(i);
                        System.out.println("存入数据-->"+i);

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){

                    try {
                        Thread.sleep(1000);
                        System.out.println("取出数据-->"+blockingQueue.take());

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        }).start();
    }
}
运行结果 

        ArrayBlockingQueue

        

        LinkedBlockingQueue

         SynchronousQueue

运行结果可以看出三种阻塞队列的特点. 

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CY是个工具人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值