Concurrent下的线程安全集合

转载 2016年08月30日 00:42:22

转自:http://www.cnblogs.com/ijavanese/p/3778688.html
1.ArrayBlockingQueue

ArrayBlockingQueue是由数组支持的线程安全的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。此类支持对等待的生产者线程和消费者线程进行排序的可选公平策略。默认情况下,不保证是这种排序。然而,通过将公平性 (fairness) 设置为 true 而构造的队列允许按照 FIFO 顺序访问线程。公平性通常会降低吞吐量,但也减少了可变性和避免了“不平衡性”。

复制代码
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
复制代码
从改造方法可以看出,ArrayBlockingQueue的实现机制是ReentrantLock和Condition来实现的。

2、LinkedBlockingDeque

LinkedBlockingDeque是用双向链表实现的,需要说明的是LinkedList也已经加入了Deque的一部分。

/* Maximum number of items in the deque /
private final int capacity;
复制代码
/**
* Creates a {@code LinkedBlockingDeque} with a capacity of
* {@link Integer#MAX_VALUE}.
*/
public LinkedBlockingDeque() {
this(Integer.MAX_VALUE);
}
复制代码
public LinkedBlockingDeque(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
}
要想支持阻塞功能,队列的容量一定是固定的,否则无法在入队的时候挂起线程。也就是capacity是final类型的。
既然是双向链表,每一个结点就需要前后两个引用,这样才能将所有元素串联起来,支持双向遍历。也即需要prev/next两个引用。
双向链表需要头尾同时操作,所以需要first/last两个节点,当然可以参考LinkedList那样采用一个节点的双向来完成,那样实现起来就稍微麻烦点。
既然要支持阻塞功能,就需要锁和条件变量来挂起线程。这里使用一个锁两个条件变量来完成此功能。

3、LinkedBlockingQueue

LinkedBlockingQueue是一个基于已链接节点的、范围任意的blocking queue的实现,也是线程安全的。按 FIFO(先进先出)排序元素。队列的头部 是在队列中时间最长的元素。队列的尾部 是在队列中时间最短的元素。

复制代码
/**
* Creates a {@code LinkedBlockingQueue} with a capacity of
* {@link Integer#MAX_VALUE}.
*/
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
复制代码
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node(null);
}
可选的容量范围构造方法参数作为防止队列过度扩展的一种方法。如果未指定容量,则它等于 Integer.MAX_VALUE。除非插入节点会使队列超出容量,否则每次插入后会动态地创建链接节点。

 此外它还不接受null值:

复制代码
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
// Note: convention in all put/take/etc is to preset local var
// holding count negative to indicate failure unless set.
int c = -1;
Node node = new Node(e);
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
复制代码

4、PriorityBlockingQueue

PriorityBlockingQueue是一个无界的线程安全的阻塞队列,它使用与PriorityQueue相同的顺序规则,并且提供了阻塞检索的操作。

public PriorityBlockingQueue(int initialCapacity) {
    this(initialCapacity, null);
}

复制代码
public PriorityBlockingQueue(int initialCapacity,
Comparator

Concurrent下的线程安全集合淄滋爪篆装状

http://www.ebay.com/cln/zhenbe5/2015-01-28/165564250015 http://www.ebay.com/cln/ainxiacen/2015-01-2...

Concurrent包总结——线程安全的集合操作

java中提供了丰富的集合类操作,大概可以分为无序结合Set,有序集合List和无序键值对集合Map。Java5之后又新增了队列操作集合Queue。Java1.5之后新增了线程安全的集合操作类,阻止在...

tbb 线程安全concurrent_queue的性能

tbb实现了线程安全的queue,这样程序员既可以不用和那些lock,mutex,criticalsection打交道,又大大提高性能,太给力了。。比较的结果见代码中的注释。结果可以看出代码足足少一半...

java.util.concurrent包介绍(2)——Java线程安全

在Java Concurrency in Practice中是这样定义线程安全的: 当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替运行,并且不需要额外的同步及在调用方代码...

Map 非线程安全的证明 以及线程安全方案(Concurrent)

参考 http://blog.csdn.net/nx188/article/details/50988037一、概述       大部分容器(比如:List、Map、Set)都是设计成非线程安全的,...

java各种集合的线程安全

java集合的线程安全
  • glDemo
  • glDemo
  • 2015年03月26日 18:48
  • 21207

建议22:确保集合的线程安全

建议22:确保集合的线程安全 集合线程安全是指多个线程上添加或删除元素时,线程键必须保持同步。 下面代码模拟了一个线程在迭代过程中,另一个线程对元素进行了删除。 clas...
  • houwc
  • houwc
  • 2016年09月01日 13:24
  • 149

java各种集合的线程安全

java各种集合的线程安全 线程安全 首先要明白线程的工作原理,jvm有一个main memory,而每个线程有自己的working  memory,一个线程对一个varia...

C# 4.0 之线程安全集合篇

作为多线程和并行计算不得不考虑的问题就是临界资源的访问问题,解决临界资源的访问通常是加锁或者是使用信号量,这个大家应该很熟悉了。   而集合作为一种重要的临界资源,通用性更广,为了让大家更安全的使用...

多核时代 .NET Framework 4 中的并行编程9---线程安全集合类

在.Net 4中,新增System.Collections.Concurrent 命名空间中提供多个线程安全集合类,这些类提供了很多有用的方法用于访问集合中的元素,从而可以避免使用传统的锁(lock)...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Concurrent下的线程安全集合
举报原因:
原因补充:

(最多只允许输入30个字)