java线程之阻塞队列

简介: java线程之阻塞队列

一、什么是阻塞队列

阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。 这两个附加的操作支持阻塞的插入和移除方法 1)支持阻塞的插入方法:意思是当队列满时,队列会阻塞插入元素的线程,直到队列不满。 2)支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空 阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加元素的线程,消费者是从队列里取元素的线程。 阻塞队列就是生产者用来存放元素、消费者用来获取元素的容器。

二、常见阻塞队列

ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列;

LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列;

PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列;


DelayQueue:一个使用优先级队列实现的无界阻塞队列;


SynchronousQueue:一个不存储元素的阻塞队列;


LinkedTransferQueue:一个由链表结构组成的无界阻塞队列(实现了继承于 BlockingQueue 的 TransferQueue);


LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列;

三、阻塞队列的操作方法

BlockingQueue 有四种形式的 API。

方法类型

抛出异常

返回特殊值

一直阻塞

超时退出

插入

add(e)

offer(e)

put(e)

offer(e,time,unit)

移除(取出)

remove()

poll()

take()

poll(time,unit)

检查

element()

peek()

不可用

不可用

以 ArrayBlockingQueue 为例

1、add(e)

public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue=new ArrayBlockingQueue<>(2);
        for (int i = 0; i < 3; i++) {
            String substring = UUID.randomUUID().toString().substring(0, 8);
            //add插入元素,队列满时,抛出异常java.lang.IllegalStateException: Queue full
            boolean add = blockingQueue.add(substring);
            System.out.println(add);
        }
    }

2、offer(e)

public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue=new ArrayBlockingQueue<>(2);
 
        for (int i = 0; i < 3; i++) {
            String substring = UUID.randomUUID().toString().substring(0, 8);
            //offer无参构造,插入元素,队列满时,返回false
            boolean offer = blockingQueue.offer(substring);
            System.out.println(offer);
        }
    }

3、put(e)

 public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue=new ArrayBlockingQueue<>(2);
        for (int i = 0; i < 3; i++) {
            String substring = UUID.randomUUID().toString().substring(0, 8);
            //队列满时,阻塞线程
            blockingQueue.put(substring);
            System.out.println((i+1)+"队列长度:"+blockingQueue.size());
        }
 
    }

4、offer(e,time,unit)

   public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue=new ArrayBlockingQueue<>(2);
        for (int i = 0; i < 3; i++) {
            String substring = UUID.randomUUID().toString().substring(0, 8);
            //队列满时,等待5秒,重试一次
            blockingQueue.offer(substring, 5,TimeUnit.SECONDS);
            System.out.println((i+1)+"队列长度:"+blockingQueue.size());
        }
    }

5、remove()

 public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(2);
        for (int i = 0; i < 2; i++) {
            String substring = UUID.randomUUID().toString().substring(0, 8);
            //add插入元素,队列满时,抛出异常java.lang.IllegalStateException: Queue full
            blockingQueue.add(substring);
        }
        for (int i = 0; i < 3; i++) {
            //移除一个元素,当队列为空,java.util.NoSuchElementException
            System.out.println(blockingQueue.remove());
        }
    }


 

6、poll()

 public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(2);
        for (int i = 0; i < 2; i++) {
            String substring = UUID.randomUUID().toString().substring(0, 8);
            //add插入元素,队列满时,抛出异常java.lang.IllegalStateException: Queue full
            blockingQueue.add(substring);
        }
        for (int i = 0; i < 3; i++) {
            //移除一个元素,当队列为空,返回null
            System.out.println(blockingQueue.poll());
        }
    }

 

7、take()

 public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(2);
        for (int i = 0; i < 2; i++) {
            String substring = UUID.randomUUID().toString().substring(0, 8);
            //add插入元素,队列满时,抛出异常java.lang.IllegalStateException: Queue full
            blockingQueue.add(substring);
        }
        for (int i = 0; i < 3; i++) {
            //移除一个元素,当队列为空,阻塞线程
            System.out.println(blockingQueue.take());
        }
    }

 

8、poll(time,unit)

public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(2);
        for (int i = 0; i < 2; i++) {
            String substring = UUID.randomUUID().toString().substring(0, 8);
            //add插入元素,队列满时,抛出异常java.lang.IllegalStateException: Queue full
            blockingQueue.add(substring);
        }
        for (int i = 0; i < 3; i++) {
            //移除一个元素,当队列为空,阻塞1s
            System.out.println(blockingQueue.poll(1, TimeUnit.SECONDS));
        }
    }

       

9.element()、peek()

 public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(2);
        for (int i = 0; i < 2; i++) {
            String substring = UUID.randomUUID().toString().substring(0, 8);
            //add插入元素,队列满时,抛出异常java.lang.IllegalStateException: Queue full
            blockingQueue.add(substring);
        }
        System.out.println(JSON.toJSONString(blockingQueue));
        for (int i = 0; i < 2; i++) {
            //移除一个元素,当队列为空,返回null
            System.out.println(blockingQueue.remove());
        }
        //检查队列,返回队列头部元素,如果队列为空返回null
        System.out.println(blockingQueue.peek());
        //检查队列,返回队列先头部元素,如果队列为空返回java.util.NoSuchElementException
        System.out.println(blockingQueue.element());
    }


 

相关文章
|
3天前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
5天前
|
Java 开发者
Java中的多线程基础与应用
【9月更文挑战第22天】在Java的世界中,多线程是一块基石,它支撑着现代并发编程的大厦。本文将深入浅出地介绍Java中多线程的基本概念、创建方法以及常见的应用场景,帮助读者理解并掌握这一核心技术。
|
1天前
|
Java 调度
Java-Thread多线程的使用
这篇文章介绍了Java中Thread类多线程的创建、使用、生命周期、状态以及线程同步和死锁的概念和处理方法。
Java-Thread多线程的使用
|
7天前
|
Java
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
21 7
|
6天前
|
Java 程序员
Java中的多线程基础与实践
【9月更文挑战第21天】本文旨在引导读者深入理解Java多线程的核心概念,通过生动的比喻和实例,揭示线程创建、同步机制以及常见并发工具类的使用。文章将带领读者从理论到实践,逐步掌握如何在Java中高效地运用多线程技术。
|
4天前
|
Java 调度 开发者
Java中的多线程编程:从基础到实践
本文旨在深入探讨Java多线程编程的核心概念和实际应用,通过浅显易懂的语言解释多线程的基本原理,并结合实例展示如何在Java中创建、控制和管理线程。我们将从简单的线程创建开始,逐步深入到线程同步、通信以及死锁问题的解决方案,最终通过具体的代码示例来加深理解。无论您是Java初学者还是希望提升多线程编程技能的开发者,本文都将为您提供有价值的见解和实用的技巧。
14 2
|
6天前
|
Java 数据处理
Java中的多线程编程:从基础到实践
本文旨在深入探讨Java中的多线程编程,涵盖其基本概念、创建方法、同步机制及实际应用。通过对多线程基础知识的介绍和具体示例的演示,希望帮助读者更好地理解和应用Java多线程编程,提高程序的效率和性能。
18 1
|
1天前
|
Java 数据处理 调度
Java中的多线程编程:从基础到实践
本文深入探讨了Java中多线程编程的基本概念、实现方式及其在实际项目中的应用。首先,我们将了解什么是线程以及为何需要多线程编程。接着,文章将详细介绍如何在Java中创建和管理线程,包括继承Thread类、实现Runnable接口以及使用Executor框架等方法。此外,我们还将讨论线程同步和通信的问题,如互斥锁、信号量、条件变量等。最后,通过具体的示例展示了如何在实际项目中有效地利用多线程提高程序的性能和响应能力。
|
2天前
|
安全 算法 Java
Java中的多线程编程:从基础到高级应用
本文深入探讨了Java中的多线程编程,从最基础的概念入手,逐步引导读者了解并掌握多线程开发的核心技术。无论是初学者还是有一定经验的开发者,都能从中获益。通过实例和代码示例,本文详细讲解了线程的创建与管理、同步与锁机制、线程间通信以及高级并发工具等主题。此外,还讨论了多线程编程中常见的问题及其解决方案,帮助读者编写出高效、安全的多线程应用程序。
|
4天前
|
存储 缓存 Java
JAVA并发编程系列(11)线程池底层原理架构剖析
本文详细解析了Java线程池的核心参数及其意义,包括核心线程数量(corePoolSize)、最大线程数量(maximumPoolSize)、线程空闲时间(keepAliveTime)、任务存储队列(workQueue)、线程工厂(threadFactory)及拒绝策略(handler)。此外,还介绍了四种常见的线程池:可缓存线程池(newCachedThreadPool)、定时调度线程池(newScheduledThreadPool)、单线程池(newSingleThreadExecutor)及固定长度线程池(newFixedThreadPool)。