JUC- 阻塞队列

7.1 基本概念

队列(queue) :是只允许在一端(头部: front)进行插入操作,而在另一端==(尾部:rear)==进行删除操作的线性表。

特点:队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端为队尾,允许删除的一端称为对头

7.2 BlockingQueue

阻塞:必须要阻塞、不得不阻塞

阻塞队列是一个队列,在数据结构中起的作用如下图

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

7.2.1 阻塞队列的用处

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

好处是不需要关心什么时候需要阻塞线程,什么时候需要唤醒线程,因为这一切BlockingQueue 都可以处理好。

7.3 接口架构

7.3.1 接口架构图

  • ArrayBlockingQueue:由数组结构组成的有界阻塞队列。
  • LinkedBlockingQueue:由链表结构组成的有界(默认值为:integer.MAX_VALUE)阻塞队列。

7.3.2 常用API

方法\处理方法 抛出异常 返回特殊值 一直阻塞 超时退出
插入方法 add(e) offer(e) put(e) offer(e, time, unit)
移除方法 remove( ) poll( ) take( ) poll(time, unit)
检查方法 element( ) peek( ) 不可用 不可用

抛出异常

package cn.guardwhy.BlockingQueue;

import java.util.concurrent.ArrayBlockingQueue;

/*
抛出异常
*/
public class BlockingQueueDemo01 {
    
    
    public static void main(String[] args) {
    
    
        // 1.队列的大小
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
        // 2.添加元素
        System.out.println(blockingQueue.add("kobe"));
        System.out.println(blockingQueue.add("curry"));
        System.out.println(blockingQueue.add("James"));
        // java.lang.IllegalStateException: Queue full
        // System.out.println(blockingQueue.add("Durant"));

        System.out.println("=========");
        System.out.println("队首元素:" + blockingQueue.element()); // 查看队首元素?

        // 3.出队操作
        System.out.println("=========");
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        // java.util.NoSuchElementException,抛出异常
        // System.out.println(blockingQueue.remove());
    }
}

返回特殊值

package cn.guardwhy.BlockingQueue;

import java.util.concurrent.ArrayBlockingQueue;

public class BlockingQueueDemo02 {
    
    
    public static void main(String[] args) {
    
    
        // 1.队列的大小
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
        // 2.添加元素
        System.out.println(blockingQueue.offer("kobe"));
        System.out.println(blockingQueue.offer("curry"));
        System.out.println(blockingQueue.offer("James"));
        System.out.println(blockingQueue.offer("Durant"));

        System.out.println("=========");
        System.out.println("队首元素:" + blockingQueue.peek()); // 查看队首元素?

        // 3.出队操作
        System.out.println("=========");
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());   // null 不抛出异常
    }
}

一直阻塞

package cn.guardwhy.BlockingQueue;

import java.util.concurrent.ArrayBlockingQueue;

public class BlockingQueueDemo03 {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        // 1.队列的大小
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
        // 2.添加元素
        blockingQueue.put("kobe");
        blockingQueue.put("Durant");
        blockingQueue.put("James");
        // blockingQueue.put("curry"); 一直阻塞


        // 3.出队操作
        System.out.println("=========");
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        // System.out.println(blockingQueue.take());// 阻塞不停止等待
    }
}

超时退出

package cn.guardwhy.BlockingQueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

public class BlockingQueueDemo04 {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        // 1.队列的大小
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
        // 2.添加元素
        blockingQueue.offer("kobe");
        blockingQueue.offer("Durant");
        blockingQueue.offer("James");
        blockingQueue.offer("curry", 3, TimeUnit.SECONDS); // 等待超过3秒就退出 


        // 3.出队操作
        System.out.println("=========");
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll(3, TimeUnit.SECONDS));// 等待超过3s就退出
    }
}

7.4 SynchronousQueue

7.4.1 同步队列

SynchronousQueue是BlockingQueue的实现类。SynchronousQueue 没有容量,与其他的 BlockingQueue 不同,SynchronousQueue是一个不存储元素的 BlockingQueue ,每一个put操作必须要等待一个take操作,否则不能继续添加元素。

7.4.2 代码示例

package cn.guardwhy.BlockingQueue;

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

public class SynchronousQueueDemo05 {
    
    
    public static void main(String[] args) {
    
    
        // 1.创建队列
        BlockingQueue<String> blockingQueue = new SynchronousQueue<>();
        // 2.添加元素
        new Thread(()->{
    
    
            try {
    
    
                System.out.println(Thread.currentThread().getName() + "1");
                blockingQueue.put(" curry");
                System.out.println(Thread.currentThread().getName() + "2");
                blockingQueue.put(" kobe");
                System.out.println(Thread.currentThread().getName() + "3");
                blockingQueue.put(" james");
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }, "NBA").start();

        new Thread(()->{
    
    
            // 延迟3s
            try {
    
    
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName() + blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName() + blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName() + blockingQueue.take());
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        },"NBA").start();
    }
}

执行结果

猜你喜欢

转载自blog.csdn.net/hxy1625309592/article/details/114072754