设为首页 加入收藏

TOP

Java并发包——线程安全的Collection相关类(四)
2019-09-03 00:51:17 】 浏览:48
Tags:Java 发包 线程 安全 Collection 相关
ptibly();
23 try { 24 while (count == items.length) 25 notFull.await(); 26 enqueue(e); 27 } finally { 28 lock.unlock(); 29 } 30 } 31 32 // 实际上的添加方法,添加成功后会唤醒一个等待删除元素的线程。 33 private void enqueue(E x) { 34 final Object[] items = this.items; 35 items[putIndex] = x; 36 if (++putIndex == items.length) 37 putIndex = 0; 38 count++; 39 notEmpty.signal(); 40 }

删除元素

ArrayBlockingQueue提供了poll()方法和take()方法两种方式删除元素。

poll()方法删除失败会立即返回false,并且添加过程中不允许被其他线程中断。

take()方法删除失败会等待,并且在删除过程中可以被其他线程中断,抛出InterruptedException异常。

 1 // 不允许被其他线程中断,删除失败则立即返回null。
 2 public E poll() {
 3     final ReentrantLock lock = this.lock;
 4     lock.lock();
 5     try {
 6         return (count == 0) ? null : dequeue();
 7     } finally {
 8         lock.unlock();
 9     }
10 }
11 
12 // 允许被其他线程中断,抛出InterruptedException,并且删除失败会等待。
13 public E take() throws InterruptedException {
14     final ReentrantLock lock = this.lock;
15     lock.lockInterruptibly();
16     try {
17         while (count == 0)
18             notEmpty.await();
19         return dequeue();
20     } finally {
21         lock.unlock();
22     }
23 }
24 
25 // 实际上的删除方法,删除成功后会唤醒一个等待添加元素的线程。
26 private E dequeue() {
27     final Object[] items = this.items;
28     @SuppressWarnings("unchecked")
29     E x = (E) items[takeIndex];
30     items[takeIndex] = null;
31     if (++takeIndex == items.length)
32         takeIndex = 0;
33     count--;
34     if (itrs != null)
35         itrs.elementDequeued();
36     notFull.signal();
37     return x;
38 }

LinkedBlockingQueue

说明

LinkedBlockingQueue是一个单向链表实现的阻塞队列。该队列按FIFO(先进先出)排序元素,新元素插入到队列的尾部,并且队列获取操作会获得位于队列头部的元素。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。

LinkedBlockingQueue是可选容量的(防止过度膨胀),即可以指定队列的容量。如果不指定,默认容量大小等于Integer.MAX_VALUE。

LinkedBlockingQueue实现了BlockingQueue接口,它支持多线程并发。当多线程竞争同一个资源时,某线程获取到该资源之后,其它线程需要阻塞等待。

LinkedBlockingQueue在实现多线程对竞争资源的互斥访问时,对于插入和取出操作分别使用了不同的锁。此外,插入锁putLock和非满条件notFull相关联,取出锁takeLock和非空条件notEmpty相关联。通过notFull和notEmpty更细腻的控制锁。

属性

1 head是链表的表头。取出数据时,都是从表头head处插入。
2 last是链表的表尾。新增数据时,都是从表尾last处插入。
3 count是链表的实际大小,即当前链表中包含的节点个数。
4 capacity是列表的容量,它是在创建链表时指定的。
5 putLock是插入锁。
6 takeLock是取出锁。
7 notEmpty是非空条件。
8 notFull是非满条件。

构造方法

1 // 创建一个容量为Integer.MAX_VALUE的LinkedBlockingQueue。
2 LinkedBlockingQueue()
3 // 创建一个指定容量的LinkedBlockingQueue。
4 LinkedBlockingQueue(int capacity)
5 // 创建一个容量是Integer.MAX_VALUE的LinkedBlockingQueue,最初包含给定collection的元素,元素按该collection迭代器的遍历顺序添加。
6 LinkedBlockingQueue(Collection<? extends E> c)

其他方法

 1 // 将指定元素插入到此队列的尾部,如果队列已满,则等待。
 2 void put(E e)
 3 // 将指定元素插入到此队列的尾部,如果队列已满,则返回false。
 4 boolean offer(E e)
 5 // 将指定元素插入到此队列的尾部,如果队列已满,则等待指定的时间。
 6 boolean offer(E e, long timeout, TimeUnit unit)
 7 // 获取并移除此队列的头部,如果队列为空,则等待。
 8 E take()
 9 // 获取并移除此队列的头部,如果队列为空,则返回null。
10 E poll()
11 // 获取并移除此队列的头部,如果队列为空,则等待指定的时间。
12 E poll(long timeout, TimeUnit unit)
13 // 获取但不移除此队列的头,如果此队列为空,则返回null。
14 E peek()
15 // 返回在队列中的元素上按适当顺序进行迭代的迭代器。
16 Iterator<E> iterator()

ConcurrentLinkedQueue

说明

ConcurrentLinkedQueue是线程安全的队列,它适用于“高并发”的场景。ConcurrentLinkedQueue使用CAS来保证更新的线程安全,是一个非阻塞队列。

ConcurrentLinkedQueue是一个基于链表的无界线程安全队列,按照FIFO(先进先出)原则对元素进行排序。队列元素中不可以放置null元素(内部实现的特殊节点除外)。

构造方法

1 // 创建一个最初为空的ConcurrentLinkedQueue。
2 ConcurrentLinkedQueue()
3 // 创建一个最初包含给定collection元素的ConcurrentLinkedQueue,按照此collection
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇消息中间件介绍(非原创) 下一篇RabbitMQ 消费端限流、TTL、死信..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目