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

并发集合和阻塞队列

阅读更多

 

一、阻塞队列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类中的相应方法对已有集合进行封装。

 

分享到:
评论

相关推荐

    最牛并发编程总结.png

    一共包括了java内存模型、并发基础、锁、并发工具类、java并发编程实战、优化、阻塞队列、原子操作、并发集合、线程池、线程基础、自定义并发类等13个方面的内容。 学习并发编程一张图就搞定了。

    并发容器和线程池,java并发编程3

    类,来感受⼀下JDK⾃带的并发集合带来的“快感”。 ConcurrentLinkedQueue是⼀个基于链接节点的⽆界线程安全队列,它采⽤先进先出的规则对节点 进⾏排序,当我们添加⼀个元素的时候,它会添加到队列的尾部,当我们...

    Java 7并发编程实战手册

    全书分为9章,涵盖了线程管理、线程同步、线程执行器、Fork/Join框架、并发集合、定制并发类、测试并发应用等内容。全书通过60多个简单而非常有效的实例,帮助读者快速掌握Java 7多线程应用程序的开发技术。学习完...

    面试专题-并发篇讲义.pdf

    当获取锁失败后,由可运行进入 Monitor 的阻塞队列阻塞,此时不占用 cpu 时间 当持锁线程释放锁时,会按照一定规则唤醒阻塞队列中的阻塞线程,唤醒 后的线程进入可运行状态 等待 当获取锁成功后,但由于条件不满足,...

    Java并发编程:同步容器

    为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列、Synchronizer(比如CountDownLatch)。我们来讨论下同步容器。  一.为什么会出现同步容器?  在...

    多线程高并发采集器

    3)推送数据到阻塞队列中 4)如果推送成功就发送Response(200) 5) 如果推送不成功发送Response(500) 保存数据线程 1)从阻塞队列中拉取日志数据 2)保存日志数据到服务器日志文件中 3)如果日志文件...

    java8集合源码分析-AboutJava:java相关知识(理论,代码)相关知识均是看书,博客等地方获取再由自己整理,如存在侵权,请告诉我

    BlockingQueue阻塞队列 并发 (很多笔记来自java并发艺术一书) 多线程基础 synchronized volatile 线程间的通信 锁(重入锁,读写锁) 并发工具 增强的Future CompletableFuture 线程池技术 Java线程池Executors Fork...

    这就是标题—— JUC.pdf

    JUC是什么 线程 进程 / 线程 ...BlockingQueue(阻塞队列) 线程池 池化技术 线程池的优势 线程池的特点 线程池三大方法 线程池七大参数 线程池四种拒绝策略 ForkJoin 异步回调 Volatile 指令重排 JMM

    JAVA核心知识点整理面试宝典

    JAVA核心知识点整理 java集合,jvm详解 ,java多线程,线程池高并发,java IO ,JAVA 阻塞队列原理

    Java concurrency集合之LinkedBlockingDeque_动力节点Java学院整理

    LinkedBlockingDeque是双向链表实现的双向并发阻塞队列。该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除);并且,该阻塞队列是支持线程安全。

    藏经阁-深入剖析iOS性能优化.pdf

    iOS 性能优化 ...iOS 性能优化需要考虑多方面的因素,包括集合操作优化、哈希表、GCD、QoS、NSOperationQueue、NSCache 和 I/O 优化。只有通过深入了解这些技术和方法,才能编写出高性能的 iOS 应用程序。

    java并发编程

    主要介绍java常用并发API,内容有: 基于String构建自己的锁管理器、 Collections构建不可修改的集合对象、 CopyOnWriteArrayList的应用场景、 可堵塞队列的功能及行为、 使用API实现压力测试、 CyclicBarrier与...

    XML文件_xml

    具备扎实的Java基础,熟练掌握集合,AQS,Synchronized关键字,CountDownLatch&Semaphore应用与原理,Executor线程池原理与源码,深入理解同步器AQS阻塞队列BlockingQueue,Future&ForkJoin框架原理,无锁并发框架...

    操作系统概念归纳总结

    ④ 进程是程序在一个数据集合上的运行过程,是系统进行资源分配和调度的一个独立单位。 6. 进程的基本特征:动态性、并发性、独立性、异步性、结构特征(程序+数据+PCB) 7. 进程的状态 三态:就绪状态、运行状态...

    java内核源码-JavaCompass:「Java指南针」为你学习Java指明方向。内容涵盖互联网Java工程师所需要掌握的核心知识,涉及J

    java内核源码 Java指南针 基础核心 基础知识 反射 泛型 动态代理 JDK8新特性 集合容器 多线程与并发 Spring SpringMVC SpringBoot ...并发编程 ...并发同步处理 ...阻塞队列BlockingQueue详解 并发Map、Lis

    大厂面试专栏,冲击大厂必备

    反射、泛型、IO模型、重载、非阻塞 第二篇:JAVA 集合那点破事!集合、扩容、数组、链表 第三篇:JAVA 并发!JUC、死锁、CAS、线程池 第四篇:JVM 那点破事!内存结构、垃圾收集、OOM、双亲委派 第五篇:项目亮点!...

    [详细完整版]操作系统测验.doc

    当S的值___小于0__ ___时,执行P操作的进程的状态就置为阻塞态,把相应的PCB连入该信号量队列的___末 尾 ________ ,并且该进程____放弃_______ 处理机。 4. 从用户的源程序进入系统到相应程序在机器上运行,所经历...

    2021面试题总结操作系统篇.pdf

    进程是具有一定功能的程序关于某个数据集合上的一次运行活动,是系统进行资源调度和分配的一个独立单位。进程是通过进程控制块(PCB)来控制的,主要包括进程描述、进程控制、资源和使用状况、CPU现场等信息。线程是...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【集合】HashMap在并发场景下的问题和解决方案 67 多线程put后可能导致get死循环 67 多线程put的时候可能导致元素丢失 68 解决方案 68 【集合】ConcurrentHashMap的get(),put(),又是如何实现的?ConcurrentHashMap...

    华为leetcode-comprehensive-code:综合代码

    阻塞队列 casDemo cas collectionDemo 集合juc lockDemo 锁 threadDome 线程 volatileDemo cloneDemo 拷贝 java8 date lambda methodRefe optional stream proxy algorithm 算法题 leetcode huawei sort designMode ...

Global site tag (gtag.js) - Google Analytics