多线程的共享也可以用全局变量做,全局变量可以用queue也可以不出现线程问题,局部变量需要用blockqueue才可以解决
1.BlockingQueue定义的常用方法如下
|
抛出异常 |
特殊值 |
阻塞 |
超时 |
插入 |
add(e) |
offer(e) |
put(e) |
offer(e,time,unit) |
移除 |
remove() |
poll() |
take() |
poll(time,unit) |
检查 |
element() |
peek() |
不可用 |
不可用 |
1)add(anObject):把anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则招聘异常
2)offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false.
3)put(anObject):把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续.
4)poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null
5)take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到Blocking有新的对象被加入为止
其中:BlockingQueue 不接受null 元素。试图add、put 或offer 一个null 元素时,某些实现会抛出NullPointerException。null 被用作指示poll 操作失败的警戒值。
2、BlockingQueue的几个注意点
【1】BlockingQueue 可以是限定容量的。它在任意给定时间都可以有一个remainingCapacity,超出此容量,便无法无阻塞地put 附加元素。没有任何内部容量约束的BlockingQueue 总是报告Integer.MAX_VALUE 的剩余容量。
【2】BlockingQueue 实现主要用于生产者-使用者队列,但它另外还支持Collection
接口。因此,举例来说,使用remove(x) 从队列中移除任意一个元素是有可能的。然而,这种操作通常不 会有效执行,只能有计划地偶尔使用,比如在取消排队信息时。
【3】BlockingQueue 实现是线程安全的。所有排队方法都可以使用内部锁或其他形式的并发控制来自动达到它们的目的。然而,大量的 Collection 操作(addAll、containsAll、retainAll 和removeAll)没有 必要自动执行,除非在实现中特别说明。因此,举例来说,在只添加了c 中的一些元素后,addAll(c) 有可能失败(抛出一个异常)。
【4】BlockingQueue 实质上不支持使用任何一种“close”或“shutdown”操作来指示不再添加任何项。这种功能的需求和使用有依赖于实现的倾向。例如,一种常用的策略是:对于生产者,插入特殊的end-of-stream 或poison 对象,并根据使用者获取这些对象的时间来对它们进行解释。
3、简要概述BlockingQueue常用的四个实现类
1)ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的.
2)LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的
3)PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序.
4)SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的.
其中LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue.
下面主要看一下ArrayBlockingQueue的源码:
- public boolean offer(E e) {
- if (e == null) throw new NullPointerException();
- final ReentrantLock lock = this.lock;
- lock.lock();
- try {
- if (count == items.length)
- return false;
- else {
- insert(e);
- return true;
- }
- } finally {
- lock.unlock();
- }
- }
- 看insert方法:
- private void insert(E x) {
- items[putIndex] = x;
-
-
-
-
-
-
-
-
- putIndex = inc(putIndex);
- ++count;
- notEmpty.signal();
- }
|
- public void put(E e) throws InterruptedException {
- if (e == null) throw new NullPointerException();
- final E[] items = this.items;
- final ReentrantLock lock = this.lock;
- lock.lockInterruptibly();
- try {
- try {
- while (count == items.length)
- notFull.await();
- } catch (InterruptedException ie) {
- notFull.signal();
- throw ie;
- }
- insert(e);
- } finally {
- lock.unlock();
- }
- }
|
- public boolean offer(E e, long timeout, TimeUnit unit)
- throws InterruptedException {
-
- if (e == null) throw new NullPointerException();
- long nanos = unit.toNanos(timeout);
- final ReentrantLock lock = this.lock;
- lock.lockInterruptibly();
- try {
- for (;;) {
- if (count != items.length) {
- insert(e);
- return true;
- }
- if (nanos <= 0)
- return false;
- try {
-
- nanos = notFull.awaitNanos(nanos);
- } catch (InterruptedException ie) {
- notFull.signal();
- throw ie;
- }
- }
- } finally {
- lock.unlock();
- }
- }
|
- public boolean add(E e) {
- return super.add(e);
- }
- 父类:
- public boolean add(E e) {
- if (offer(e))
- return true;
- else
- throw new IllegalStateException("Queue full");
- }
|
该类中有几个实例变量:takeIndex/putIndex/count
- 用三个数字来维护这个队列中的数据变更:
-
- private int takeIndex;
-
- private int putIndex;
-
- private int count;
|
相关推荐
Java多线程之BlockingQueue深入分析 Java多线程中,BlockingQueue是一种特殊的队列,它可以为线程同步提供有力的保障。在Java多线程(五)之BlockingQueue深入分析中,我们将深入分析BlockingQueue的定义、常用方法...
本文将深入探讨BlockingQueue的使用、特性以及常见操作。 首先, BlockingQueue接口位于`java.util.concurrent`包下,它继承自`java.util.Queue`接口,并添加了一些阻塞操作。阻塞操作指的是当队列为空时,获取元素...
阻塞队列BlockingQueue是Java并发编程中一个重要的数据结构,它是线程安全的队列,主要用于生产者消费者模型中的数据交换。在Java的`java.util.concurrent`包中,提供了多种实现阻塞队列的类,如`ArrayBlockingQueue...
本文将深入探讨 BlockingQueue 的原理、特性以及如何在实际应用中使用。 ### 1. BlockingQueue概述 BlockingQueue 是一个并发容器,它实现了队列的接口,同时具备阻塞功能。当队列为空时,尝试从队列中获取元素的...
通过阅读和分析这些代码,你可以深入理解如何在Spring MVC项目中集成和利用`BlockingQueue`和`@PostConstruct`注解。 总结来说,`spring MVC 初始启动concurrent blocking queue`涉及的是在Spring MVC应用启动时...
### 三、 blockingqueue-example 示例项目分析 在 "blockingqueue-example-master" 示例项目中,我们可以看到如何使用 BlockingQueue 进行多线程交互。项目通常包含生产者(Producer)和消费者(Consumer)两个线程...
本实例提供了源代码和详细指导教程,帮助开发者深入理解这一概念。 生产者消费者问题通常使用Java中的`java.util.concurrent`包来解决,特别是`BlockingQueue`接口。在这个例子中,`BlockingQueue`作为共享的缓冲区...
通过分析这些代码,可以更深入地理解多线程编程和Java并发机制。学习和理解这个问题对于进行高并发系统设计和优化是非常重要的,因为它是并发编程中常见的模式,广泛应用于消息队列、数据库连接池等场景。
通过分析和实践`BlockingQueueDemo`,开发者可以深入理解Android中消息队列的工作原理,提高应用程序的响应性和可维护性。这种自定义的消息队列设计对于实现复杂的定时任务、动画控制或者其他需要精细控制的任务调度...
本文将深入探讨Java多线程编程的基础知识,包括线程的创建、同步、通信以及相关实例。 一、线程的创建 在Java中,有两种主要的创建线程的方式: 1. 继承Thread类:创建一个新的类,继承自Thread类,然后重写它的...
通过这个实验,你可以深入理解Java并发编程中的同步与异步概念,以及`BlockingQueue`如何在生产者消费者问题中起到关键作用。此外,你还可以学习到如何在实际项目中使用Java的并发工具来提高多线程环境下的程序性能...
在本练习中,我们将通过`BlockingQueue1.java`和`BlockingQueue2.java`两个文件来深入理解和实践BlockQueue的基本用法和实现。 BlockQueue的核心特性在于它的阻塞操作:当队列为空时,尝试获取元素的线程会被阻塞;...
首先,我们深入理解生产者消费者模型。该模型基于“缓冲区”概念,生产者将产品放入缓冲区,而消费者从缓冲区取出产品。当缓冲区满时,生产者需要等待;当缓冲区空时,消费者也需要等待。这种机制由Java的并发工具类...
在源码层面,我们可以通过分析`BlockingQueue`接口的实现,如`ArrayBlockingQueue`、`LinkedBlockingQueue`等,来了解其内部是如何处理线程的阻塞和唤醒的。这些实现通常会用到`wait()`和`notify()`方法,或者`Lock`...
《生产者-消费者问题的深度剖析与探讨》 在计算机科学和并发编程中,"生产者-消费者"问题是一个经典的问题模型,它涉及到多...通过对提供的代码文件的分析,我们可以深入理解这一模式在实际编程中的运用和实现细节。
通过对这些代码的学习和分析,可以帮助开发者深入理解Java模拟Spooling的具体实现方法。 通过以上讲解,我们可以看到Java虽然没有内置的Spooling机制,但借助其强大的并发库和数据结构,完全可以实现一个高效的假...
生产者消费者问题是多线程编程中的一个经典案例,主要展示了线程间的同步和通信。...通过分析源码,我们可以深入理解如何利用`BlockingQueue`等工具解决这类问题,并学习到如何在多线程环境中确保程序的正确性和性能。
- **类库结构**:J.U.C提供了丰富的类库支持,包括但不限于`ExecutorService`、`Future`、`BlockingQueue`、`CountDownLatch`、`Semaphore`、`CyclicBarrier`等。 - **样例分析**:通过具体的代码示例来讲解这些类...
Java集合框架源码分析 Java集合框架是Java语言中一个非常重要的组件,提供了多种数据结构和算法来存储和操作数据。在Java集合框架中,...本文对Java集合框架的源码进行了深入分析,为读者提供了详细的参考资料。
在这个"模仿线程"生产者与消费者"的例子中,我们将深入探讨这个经典的并发设计模式及其背后的原理。 生产者-消费者模式是一种典型的同步问题,用于解决数据生产与消费的异步处理。在这个模型中,生产者线程负责创建...