`
wydyyhwzx
  • 浏览: 9526 次
社区版块
存档分类
最新评论

并发集合和阻塞队列

阅读更多

 

一、阻塞队列BlockingQueue

       BlockingQueue 是线程安全的java阻塞队列,主要应用于生产者消费者模式、消息传递、并行任务执行和相关并发设计的大多数常见使用上下文。

   BlockingQueue 可以是限定容量的。它在任意给定时间都可以有一个 remainingCapacity,超出此容量,便无法无阻塞地 put 附加元素。没有任何内部容量约束的 BlockingQueue 总是报告 Integer.MAX_VALUE 的剩余容量。

   BlockingQueue 方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:第一种是抛出一个异常,第二种是返回一个特殊值(nullfalse,具体取决于操作),第三种是在操作可以成功前,无限期地阻塞当前线程,第四种是在放弃前只在给定的最大时间限制内阻塞。下表中总结了这些方法:

 

 

 

 

  抛出异常 特殊值 阻塞 超时
插入 add(e) offer(e) put(e) offer(e, time, unit)
移除 remove() poll() take() poll(time, unit)
检查 element() peek() 不可用 不可用

 

 

阻塞队列包含以下实现:

1. ArrayBlockingQueue

        一个以数组为基础的有界阻塞队列,此队列按照先进先出原则对元素进行排序。队列头部元素是队列中存在时间最长的元素,队列尾部是存在时间最短的元素,新元素将会被插入到队列尾部。队列从头部开始获取元素。

       ArrayBlockingQueue是“有界缓存区”模型的一种实现,一旦创建了这样的缓存区,就不能再改变缓冲区的大小。ArrayBlockingQueue的一个特点是,必须在创建的时候指定队列的大小。当缓冲区已满,则需要阻塞新增的插入操作,同理,当缓冲区已空需要阻塞新增的提取操作。

       ArrayBlockingQueue是使用的是循环队列方法实现的,对ArrayBlockingQueue的相关操作的时间复杂度,可以参考循环队列进行分析。

 

2.LinkedBlockingQueue

        一种通过链表实现的阻塞队列,支持先进先出。队列的头部是队列中保持时间最长的元素,队列的尾部是保持时间最短的元素。新元素插入队列的尾部。可选的容量设置可以有效防止队列过于扩张造成系统资源的过多消耗,如果不指定队列容量,队列默认使用Integer.MAX_VALUE。LinkedBlockingQueue的特定是,支持无限(理论上)容量。

 

3.PriorityBlockingQueue

        PriorityBlockingQueue是一种基于优先级进行排队的无界队列。队列中的元素按照其自然顺序进行排列,或者根据提供的Comparator进行排序,这与构造队列时,提供的参数有关。

        使用提取方法时,队列将返回头部,具有最高优先级(或最低优先级,这与排序规则有关)的元素。如果多个元素具有相同的优先级,则同等优先级间的元素获取次序无特殊说明。

       优先级队列使用的是一种可扩展的数组结构,一般可以认为这个队列是无界的。当需要新添加一个元素时,如果此时数组已经被填满,优先队列将会自动扩充当前数组(一般认为是,先分配一个原数组一定倍数空间的数组,之后将原数组中的元素拷贝到新分配的数组中,释放原数组的空间)。

       如果使用优先级队列的iterator变量队列时,不保证遍历次序按照优先级大小进行。因为优先级队列使用的是堆结构。如果需要按照次序遍历需要使用Arrays.sort(pq.toArray())。

       在PriorityBlockingQueue的实现过程中聚合了PriorityQueue的一个实例,并且优先队列的操作完全依赖与PriorityQueue的实现。在PriorityQueue中使用了一个一维数组来存储相关的元素信息。一维数组使用最小堆算法进行元素添加。

 

4.DelayQueue

       一个无界阻塞队列,只有在延时期满时才能从中提取元素。如果没有元素到达延时期,则没有头元素。

 

 

二、并发集合

       在多线程程序中使用的集合类,与普通程序中使用的集合类是不同的。因为有可能多个线程同时访问或修改同一集合,如果使用普通集合,很可能造成相应操作出现差错,甚至崩溃。Java提供了用于线程访问安全的集合。

 

1.ConcurrentMap

        ConcurrentMap接口在Map接口的基础上提供了一种线程安全的方法访问机制。ConcurrentMap接口额外提供了多线程使用的四个方法,这四个方法实际是对Map已有方法的一个组合,并对这种组合提供一种原子操作。

        包含ConcurrentNavigableMap<K,V>  子接口,ConcurrentHashMap, ConcurrentSkipListMap两个实现类。

 

2.ConcurrentSkipListSet

        一个基于 ConcurrentSkipListMap 的可缩放并发 NavigableSet 实现。set 的元素可以根据它们的自然顺序进行排序,也可以根据创建 set 时所提供的 Comparator 进行排序,具体取决于使用的构造方法。

 

3.CopyOnWriteArrayList ,CopyOnWriteArraySet

        CopyOnWriteArrayListArrayList的一个线程安全的变体,其中对于所有的可变操作都是通过对底层数组进行一次新的复制来实现的。

       由于可变操作需要对底层的数据进行一次完全拷贝,因此开销一般较大,但是当遍历操作远远多于可变操作时,此方法将会更有效,这是一种被称为“快照”的模式,数组在迭代器生存期内不会发生更改,因此不会产生冲突。创建迭代器后,迭代器不会反映列表的添加、移除或者更改。CopyOnWriteArraySetCopyOnWriteArrayList相似,只不过是Set类的一个变体。

 

4.Collections线程封装

       Collections提供synchronizedCollectionsynchronizedListsynchronizedMap

synchronizedSetsynchronizedSortedMapsynchronizedSortedMap等方法可以完成多种集合的线程安全的包装,如果在并发度不高的情况下,可以考虑使用这些包装方法,不过由于Concurrent相关的类的出现,已经不这么提倡使用这些封装了,这些方法有些人称他们为过时的线程安全机制。

 

总结

         提供线程安全的集合简单概括分为三类,首先,对于并发性要求很高的需求可以选择以Concurrent开头的相应的集合类,这些类主要包括ConcurrentHashMap、ConcurrentLinkedQueue、ConcurrentSkipListMap、ConcurrentSkipSet。其次对于可变操作次数远远小于遍历的情况,可以使用CopyOnWriteArrayList和CopyOnWriteArraySet类。最后,对于并发规模比较小的并行需求可以选择Collections类中的相应方法对已有集合进行封装。

 

分享到:
评论

相关推荐

    BlockingQueue(阻塞队列)详解

    - **缓存管理**:在有限容量的缓存中,阻塞队列可以帮助实现缓存数据的高效更新和管理。 **4. 阻塞队列的优点** - **线程安全性**:内置线程安全机制,无需手动实现同步。 - **自动阻塞与唤醒**:当队列满时,...

    java并发集合

    在Java编程中,"java并发集合"是一个关键领域,它涉及到多线程环境下如何有效地管理和操作数据集合。Java提供了一系列的并发集合类,使得在并发环境中实现高效且线程安全的数据处理成为可能。这些集合主要存在于`...

    多线程并发集合资料.zip

    - `BlockingQueue`:阻塞队列,如`ArrayBlockingQueue`和`LinkedBlockingQueue`,在队列满或空时,线程会被阻塞,实现生产者-消费者模式。 - `CopyOnWriteArrayList` 和 `CopyOnWriteArraySet`:在读多写少的场景...

    C#并发集合的简单方法.pdf

    5. **BlockingCollection**:阻塞集合,它是一个抽象类,可以作为基础构建块来创建自定义的并发集合,提供添加和获取元素时的阻塞功能。 使用这些并发集合,开发者可以在编写多线程代码时减少对同步原语的依赖,...

    PHP中利用redis实现消息队列处理高并发请求思路详解.rar

    Redis作为一款高性能的键值数据库,常被用于构建消息队列,因为它提供了丰富的数据结构(如列表、集合、通道等)和原子操作,非常适合于实现消息的发布与订阅、入队与出队等操作。 在PHP中,我们可以使用Predis或...

    Java并发编程实战.pptx

    * 使用Java中的并发集合类和阻塞队列来实现高效的数据共享 * 使用Java中的并发编程工具和框架来实现高效的并发编程 Java并发编程实战是指在Java语言中实现多线程编程的技术和方法,以提高程序的响应速度、可靠性和...

    队列写入mysql实例

    首先,`LinkedBlockingQueue`是Java并发库`java.util.concurrent`中的一个线程安全的数据结构,它是一种阻塞队列。阻塞队列在满时会阻塞生产者,空时会阻塞消费者,这样可以很好地协调生产者和消费者的执行节奏。`...

    java 多线程 队列工厂

    并发集合 Java并发库(`java.util.concurrent`包)提供了一系列优化的线程安全集合,如`ConcurrentLinkedQueue`、`ConcurrentHashMap`等,它们在多线程环境下性能优越,减少了对锁的依赖。 在`queueFactory`...

    详细分析Java并发集合LinkedBlockingQueue的用法

    Java并发集合LinkedBlockingQueue是Java并发集合中的一种阻塞队列实现,使用链表方式实现的阻塞队列。LinkedBlockingQueue的实现主要包括链表实现、插入和删除节点、同步锁和条件等几个方面。 一、链表实现 ...

    Java 阻塞队列详解及简单使用

    Java 阻塞队列(BlockingQueue)是Java并发编程中的一个重要组件,它在多线程环境下提供了一种高效、安全的数据共享机制。在Java的`java.util.concurrent`包中,阻塞队列是一个线程安全的接口,它在生产者-消费者...

    并发容器的原理,7大并发容器详解、及使用场景

    5. LinkedBlockingQueue、ArrayBlockingQueue 和 PriorityBlockingQueue 是阻塞队列的实现,扩展了 Queue 接口,支持阻塞的插入和获取操作。它们分别基于链表、数组和优先级堆实现,其中 ArrayBlockingQueue 和 ...

    并发编程以及计算机底层原理

    6. **阻塞队列BlockingQueue**:`14-阻塞队列BlockingQueue实战及其原理分析二-fox`讲解了阻塞队列的概念。 BlockingQueue是一种特殊的队列,当队列满时,生产者线程会被阻塞;队列空时,消费者线程会被阻塞。这种...

    Java-concurrent-collections-concurrenthashmap-blockingqueue.pdf

    BlockingQueue 是 Java 并发集合框架中的一种阻塞队列实现,提供了高效的并发操作和线程安全机制。它可以实现生产者-消费者模式,用于在多线程环境中实现高效的数据生产和消费。 BlockingQueue 的特点包括: * ...

    java concurrent 精简源码

    本资源“java concurrent 精简源码”着重关注Java并发库(java.util.concurrent)的核心概念,包括阻塞队列和线程管理。下面将详细阐述这些知识点。 1. **Java并发库(java.util.concurrent)** Java并发库是Java ...

    09丨队列:队列在线程池等有限资源池中的应用1

    在实际应用中,队列的变种如循环队列、阻塞队列和并发队列在多线程编程、并发系统和操作系统中有着广泛的应用。例如,Disruptor是一个高性能的消息队列,利用循环队列实现零拷贝和最小锁竞争;Linux的环形缓存使用了...

    java并发编程实践(英文).docx

    书中还讨论了同步原语,如同步集合、并发集合、阻塞队列、中断方法和同步器,这些都是构建高效并发程序的基本构建块。 在第6章“任务执行”中,作者介绍了如何在多线程环境中执行任务,以及Executor框架的作用,它...

    java虚拟机并发编程.pdf

    9. **线程安全与性能优化**:书中会讨论如何分析和调试并发问题,如死锁、饥饿和活锁,并介绍性能优化技巧,如减少锁的使用和使用并发集合。 10. **实战演练**:作者可能通过实例代码和案例研究来加深对并发编程的...

    线程-线程池-锁-集合-Map-队列.docx

    `ArrayBlockingQueue`、`LinkedBlockingQueue`等是常见的阻塞队列实现,它们在多线程环境中能确保线程安全。 综上所述,线程、线程池、集合和队列是Java并发编程的核心概念,理解和掌握它们对于开发高效、稳定的...

    java并发程序设计

    Java并发程序设计是Java编程技术中一个重要的领域,它涉及如何在多线程环境下...在并发程序设计中,正确使用阻塞队列、锁机制、lock-free技术、流程控制和定时器等工具,能够帮助开发者编写出高效且稳定的并发程序。

Global site tag (gtag.js) - Google Analytics