Java并发编程_并发集合

Java并发集合框架

非阻塞式集合:这类集合包括添加和移除的方法,如果方法不能立即被执行,则返回null或抛出异常,但是调用这个方法的线程不会被阻塞。

阻塞式集合:这类集合也包括添加和移除的数据方法。当集合已满或为空时,被调用的添加或者移除方法就不能立即被执行,那么调用这个方法的线程将被阻塞,一直到该方法可以被成功执行。


1. 非阻塞集合

ConcurrentLinkedQueue
  1. 一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部是队列中存在时间最长的元素。队列的尾部是队列中存在时间最短的元素。新的元素插入到队列的尾部,队列获取操作从队列头部获得元素。当多个线程共享访问一个公共
    collection 时,ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许使用 null 元素。
    此实现采用了有效的“无等待 (wait-free)”算法

  2. 需要注意的是,与大多数 collection 不同,size 方法不是 一个固定时间操作。由于这些队列的异步特性,确定当前元素的数量需要遍历这些元素。

  3. 内存一致性效果:当存在其他并发 collection 时,将对象放入 ConcurrentLinkedQueue 之前的线程中的操作 happen-before 随后通过另一线程从 ConcurrentLinkedQueue 访问或移除该元素的操作。 也就是A线程向ConcurrentLinkedQueue集合添加O对象的操作必须在B线程从该集合中将O对象删除的操作之前执行

ConcurrentLinkedQueue详细介绍

ConcurrentLinkedDeque
  1. 基于链接节点的无界并发双端队列。并发插入,删除和访问操作可跨多个线程安全执行。当许多线程共享对公共集合的访问权时,ConcurrentLinkedDeque是一个合适的选择。与大多数其他并发集合实现一样,此类不允许使用null元素。这个类不仅可以操控头部,也可以操控尾部

  2. 请注意,与大多数集合不同,size方法不是恒定时间操作。由于这些deques的异步性质,确定元素的当前数量需要遍历元素,因此如果在遍历期间修改此集合,则可能报告不准确的结果。此外,批量操作addAll,removeAll,retainAll,containsAll,equals和toArray不保证以原子方式执行。例如,与addAll操作同时运行的迭代器可能只查看一些添加的元素。

  3. 内存一致性效果:与其他并发集合一样,将对象放入ConcurrentLinkedDeque的操作发生在从另一个线程中的ConcurrentLinkedDeque访问或删除该元素之后的操作之前。

2. 阻塞集合

ArrayBlockingQueue
  1. 一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。

  2. 这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。

ArrayBlockingQueue详细介绍

LinkedBlockingQueue
  1. 一个基于已链接节点的、范围任意的阻塞队列。此队列按 FIFO(先进先出)排序元素。队列的头部 是在队列中时间最长的元素。队列的尾部 是在队列中时间最短的元素。新元素插入到队列的尾部,并且队列获取操作会获得位于队列头部的元素。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。
  2. 可选的容量范围构造方法参数作为防止队列过度扩展的一种方法。如果未指定容量,则它等于
    Integer.MAX_VALUE。除非插入节点会使队列超出容量,否则每次插入后会动态地创建链接节点。
LinkedBlockingDeque

一个基于已链接节点的、任选范围的阻塞双端队列。 可选的容量范围构造方法参数是一种防止过度膨胀的方式。如果未指定容量,那么容量将等于 Integer.MAX_VALUE。只要插入元素不会使双端队列超出容量,每次插入后都将动态地创建链接节点。

LinkedBlockingDeque详细介绍

PriorityBlockingQueue

使用的无界阻塞队列基于heap实现。虽然这个队列是逻辑上的无限制,尝试添加可能会因资源耗尽而失败。所有添加进PriorityBlockingQueue的元素必须实现Comparable接口

PriorityBlockingQueue详细介绍

DelayQueue

Delayed 元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部 是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且 poll 将返回 null。当一个元素的
getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于等于 0 的值时,将发生到期。即使无法使用 take 或
poll 移除未到期的元素,也不会将这些元素作为正常元素对待。例如,size 方法同时返回到期和未到期元素的计数。此队列不允许使用 null
元素。

DelayQueue详细介绍

SynchronousQueue
  1. 一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作 ,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有。不能在同步队列上进行peek,因为仅在试图要移除元素时,该元素才存在;除非另一个线程试图移除某个元素,否则也不能(使用任何方法)插入元素;也不能迭代队列,因为其中没有元素可用于迭代。队列的头是尝试添加到队列中的首个已排队插入线程的元素;如果没有这样的已排队线程,则没有可用于移除的元素并且 poll() 将会返回null。对于其他 Collection 方法(例如 contains),SynchronousQueue 作为一个空 collection。此队列不允许 null 元素。

  2. 同步队列类似于 CSP 和 Ada 中使用的 rendezvous。它非常适合于传递性设计,在这种设计中,在一个线程中运行的对象要将某些信息、事件或任务传递给在另一个线程中运行的对象,它就必须与该对象同步。

  3. 对于正在等待的生产者和使用者线程而言,此类支持可选的公平排序策略。默认情况下不保证这种排序。但是,使用公平设置为 true, 所构造的队列可保证线程以 FIFO 的顺序进行访问。

  4. 当使用put()时,如果数据没被取走,那么该线程会一直阻塞。直到被take()才会被释放。offer()只有插入的时候正好被调用才会插入成功,一般会有一个线程在调用take()或poll()方法来等待,不然offer一般都会失败返回null。不要用add()方法,一般都会抛出异常。

SynchronousQueue详细介绍

LinkedTransferQueue

一个无边界的阻塞队列,基于链表实现。这个主要有transfer方法,如果加入的数据没有被消费掉,当前线程会一直阻塞。 tryTransfer(e, timeout, unit) 在一段时间内如果没有被获取就返回false,
transfer加入的数据都是在链表尾部,如果队列之前有数据,task会先取之前的数据。

LinkedTransferQueue详细介绍

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值