BlockingQueue相关

{
"title":"BlockingQueue相关",
"date":2020-05-21T09:17:16+08:00,
"draft":true,
"tags":["阻塞队列"],
"comments":true,
"share":true
}

1.BlockingQueue(阻塞队列)的介绍

阻塞队列(BlockingQueue,)是队列的一种,其特点包括队列的特点:先进先出。还有的特点如下:

(1)当阻塞队列是空时,从队列中获取元素的操作将会被阻塞。
(2)当阻塞队列是满时,往队列中添加元素的操作将会被阻塞。

BlockingQueue(BlockingQueue是接口,以下都是实现类)实现类的种类:

1 ArrayBlockingQueue: 由数组结构组成的有界阻塞队列.
2 LinkedBlockingDeque: 由链表结构组成的有界(但大小默认值Integer>MAX_VALUE,其实无界)阻塞队列.
3 PriorityBlockingQueue:支持优先级排序的无界阻塞队列.
4 DelayQueue: 使用优先级队列实现的延迟无界阻塞队列.
5 SynchronousQueue:不存储元素的阻塞队列,也即是单个元素的队列.
6 LinkedTransferQueue:由链表结构组成的无界阻塞队列.
7 LinkedBlockingDeque:由了解结构组成的双向阻塞队列.

注意:synchronousQueue是不存储元素的阻塞队列,也就是说SynchronousQueue没有容量,与其他的BlcokingQueue实现类不同,每个put操作必须要等待一个take操作,否则不能继续添加元素,反之亦然。

2.BlockingQueue的常见方法

  4.常见方法:
      方法类型        抛出异常         特殊值           阻塞           超时

      插入            add(e)         offer(e)        put(e)        offer(e,time,unit)

      移除           remove()         poll()         take()        poll(time,unit)

      检查           element()         peek()        不可用         不可用
      检查就是返回队列的第一个元素

 抛出异常(不正常的操作就报异常):
          当阻塞队列满时,再往队列里面add插入元素会抛IllegalStateException: Queue full
          当阻塞队列空时,再往队列remove元素时候回抛出NoSuchElementException

 特殊值(不正常的操作就返回特殊值):
          插入方法,成功返回true 失败返回false
          移除方法,成功返回元素,队列里面没有就返回null

 一直阻塞(不正常的操作就一直阻塞,慎用,不会用容易出问题):
           当阻塞队列满时,生产者继续往队列里面put元素,队列会一直阻塞直到put数据or响应中断退出
           当阻塞队列空时,消费者试图从队列take元素,队列会一直阻塞消费者线程直到队列可用.

 超时退出(不正常的操作就超时退出:过时不候):
          当阻塞队列满时,队列会阻塞生产者线程一定时间,超过后限时后生产者线程就会退出

3.SynchronousQueue代码演示

package com.xpf.Interview.juc.QueueDemo;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Xia
 * @Date: 2020/5/21 10:50
 * @Email:x2358114512@163.com
 */
public class T {
    public static void main(String[] args) {
        synchronousQueue();
    }

    private static void synchronousQueue() {
        BlockingQueue<Integer>  blockingQueue = new SynchronousQueue<>();

        new Thread(() -> {
            try {
                System.out.println(Thread.currentThread().getName()+"线程正在插入第一个元素:"+1);
                blockingQueue.put(1);

                System.out.println(Thread.currentThread().getName()+"线程正在插入第二个元素:"+2);
                blockingQueue.put(2);

                System.out.println(Thread.currentThread().getName()+"线程正在插入第三个元素:"+3);
                blockingQueue.put(3);

            }catch (Exception e){
                e.printStackTrace();
            }
        },"AAA").start();


        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName()+
                        "线程正在取出第一个元素:"+ blockingQueue.take());
                System.out.println("--------------------------------------");

                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName()+
                        "线程正在取出第二个元素:"+blockingQueue.take());
                System.out.println("--------------------------------------");

                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName()+
                        "线程正在取出第三个元素:"+blockingQueue.take());
                blockingQueue.put(3);

            }catch (Exception e){
                e.printStackTrace();
            }
        },"BBB").start();
    }
}

 synchronousQueue函数运行结果:
           AAA线程正在插入第一个元素:1
            BBB线程正在取出第一个元素:1
            --------------------------------------
            AAA线程正在插入第二个元素:2
            BBB线程正在取出第二个元素:2
            --------------------------------------
            AAA线程正在插入第三个元素:3
            BBB线程正在取出第三个元素:3

4.BlockQueue实现生产者-消费者模式代码演示

全部评论

相关推荐

10-30 16:31
重庆大学 Java
代码飞升_不回私信人...:你说你善于学习,大家都会说。你说你是985,985会替你表达一切
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务