阻塞队列的种类与核心方法

什么是阻塞队列?

当阻塞队列为空时,从队列中获取元素被阻塞;

当阻塞队列为满时,从队列中添加元素被阻塞;

阻塞队列的优点

不需要关心线程安全问题

如线程安全的生产者消费者模型中,

多线程:(叫卖)

生产者线程与消费者线程需要不断的使用wait()/notify() 来保证线程安全问题。

阻塞队列:(商店)

产者生产产品放入商店(对应:线程将元素放入阻塞队列),消费者在商店中消费产品(对应:线程从阻塞队列中获取元素);当商店中的产品消费空了,消费者无法再在商店中消费产品(对应:阻塞队列为空时,线程无法从阻塞队列中获取元素);当商店装满了铲平时,生产者无法在放入产品(对应:阻塞队列满时,线程无法再添加元素)。

阻塞队列的种类

  • ArrayBlockingQueue:由数组结构构成的有界阻塞队列。

  • LinkedBlockingQueue:由链表构成的有界(默认大小值为Integer.MAX_VALUE)阻塞队列。

  • PriorityBlockingQueue:支持优先级排序的无界阻塞队列。

  • DelayQueue:使用优先级队列实现的延迟无界阻塞队列。

  • SynchronousQueue:不存储元素的阻塞队列,即单元素阻塞队列。

  • LinkedTransferQueue:由链表结构组成的无界阻塞队列。

  • LinkedBlockingDeque:由链表结果组成的双向阻塞队列。

阻塞队列核心方法

抛出异常组:

添加add(),移除remove(),检查element()

add()remove()方法有boolean型返回值,添加移除成功返回true,否则抛出异常

element()方法有Object返回值,返回队列头元素,若队列空抛出异常。

代码演示add() 方法:

import java.util.concurrent.*;

public class BlockingQueueDemo {
    public static void main(String[] args){
        BlockingQueue<Integer> bq = new ArrayBlockingQueue<>(3);    //大小为3

        System.out.println(bq.add(1));
        System.out.println(bq.add(2));
        System.out.println(bq.add(3));
        System.out.println(bq.add(4));
    }
}

代码输出:

true
true
true
Exception in thread "main" java.lang.IllegalStateException: Queue full
返回布尔组:

添加offer(),移除poll(),检查peek()

添加、移除成功返回true,失败返回false

检查成功返回队列头元素,否则返回空

不多说,直接上演示代码:

import java.util.concurrent.*;

public class BlockingQueueDemo {
    public static void main(String[] args){
        BlockingQueue<Integer> bq = new ArrayBlockingQueue<>(3);

        System.out.println(bq.peek());

        System.out.println(bq.offer(1));
        System.out.println(bq.offer(2));
        System.out.println(bq.offer(3));
        System.out.println(bq.offer(4));

        System.out.println(bq.peek());

        System.out.println(bq.poll());
        System.out.println(bq.poll());
        System.out.println(bq.poll());
        System.out.println(bq.poll());
    }
}

代码输出:

null
true
true
true
false
1
1
2
3
null

Process finished with exit code 0
阻塞组:

添加put(),移除take()

当阻塞队列已满,继续调用put 方法,队列会阻塞线程直到可以有其他线程获取元素;

当阻塞队列为空,继续调用take方法,队列会阻塞线程直到可以有其他线程添加元素。

代码演示put()方法:

import java.util.concurrent.*;

public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Integer> bq = new ArrayBlockingQueue<>(3);

        bq.put(1);
        bq.put(2);
        bq.put(3);
        System.out.println("A");
        bq.put(4);
        System.out.println("B");
    }
}

代码输出:

A

没错,只有一个A,没有B,也没有Process finished with exit code 0,因为当前线程正在等待其他线程从阻塞队列中取走一个元素。

超时控制组:

添加offer(),移除poll()
顾名思义,超时控制是阻塞的升级版,阻塞一定时间后会自动结束。

如下图:offer提供了两种参数的调用方法,第二种可以设置阻塞时间。
offer方法

代码演示offer方法:

public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Integer> bq = new ArrayBlockingQueue<>(3);

        System.out.println(bq.offer(1, 2L, TimeUnit.SECONDS));
        System.out.println(bq.offer(1, 2L, TimeUnit.SECONDS));
        System.out.println(bq.offer(1, 2L, TimeUnit.SECONDS));
        System.out.println(bq.offer(1, 2L, TimeUnit.SECONDS));
    }
}

代码输出:

true
true
true
false

Process finished with exit code 0

程序首先输出三个true,停顿2秒后输出false,小伙伴们可以复制代码自己尝试一下。

个人学习总结,如果疏漏、错误之处,欢迎指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值