设为首页 加入收藏

TOP

Java并发包——线程安全的Collection相关类(三)
2019-09-03 00:51:17 】 浏览:47
Tags:Java 发包 线程 安全 Collection 相关
) 25 public E next() { 26 if (! hasNext()) 27 throw new NoSuchElementException(); 28 return (E) snapshot[cursor++]; 29 } 30 31 // 获取上一个元素。 32 @SuppressWarnings("unchecked") 33 public E previous() { 34 if (! hasPrevious()) 35 throw new NoSuchElementException(); 36 return (E) snapshot[--cursor]; 37 } 38 39 // 获取下一个元素的位置。 40 public int nextIndex() { 41 return cursor; 42 } 43 44 // 获取上一个元素的位置。 45 public int previousIndex() { 46 return cursor-1; 47 } 48 49 // 不支持删除元素。 50 public void remove() { 51 throw new UnsupportedOperationException(); 52 } 53 54 // 不支持修改元素。 55 public void set(E e) { 56 throw new UnsupportedOperationException(); 57 } 58 59 // 不支持添加元素。 60 public void add(E e) { 61 throw new UnsupportedOperationException(); 62 } 63 64 // Java1.8新增的方法,使用迭代器Iterator的所有元素,并且第二次调用它将不会做任何事情。 65 @Override 66 public void forEachRemaining(Consumer<? super E> action) { 67 Objects.requireNonNull(action); 68 Object[] elements = snapshot; 69 final int size = elements.length; 70 for (int i = cursor; i < size; i++) { 71 @SuppressWarnings("unchecked") E e = (E) elements[i]; 72 action.accept(e); 73 } 74 cursor = size; 75 } 76 }

ArrayBlockingQueue

说明

ArrayBlockingQueue内部是通过Object[]数组保存数据的,也就是说ArrayBlockingQueue本质上是通过数组实现的。ArrayBlockingQueue的大小,即数组的容量是创建ArrayBlockingQueue时指定的。

ArrayBlockingQueue与ReentrantLock是组合关系,ArrayBlockingQueue中包含一个ReentrantLock对象。ReentrantLock是可重入的互斥锁,ArrayBlockingQueue就是根据该互斥锁实现“多线程对竞争资源的互斥访问”。而且,ReentrantLock分为公平锁和非公平锁,关于具体使用公平锁还是非公平锁,在创建ArrayBlockingQueue时可以指定,ArrayBlockingQueue默认会使用非公平锁。

ArrayBlockingQueue与Condition是组合关系,ArrayBlockingQueue中包含两个Condition对象。而且,Condition又依赖于ArrayBlockingQueue而存在,通过Condition可以实现对ArrayBlockingQueue的更精确的访问。

构造方法

 1 public ArrayBlockingQueue(int capacity) {
 2     this(capacity, false);
 3 }
 4 
 5 public ArrayBlockingQueue(int capacity, boolean fair) {
 6     if (capacity <= 0)
 7         throw new IllegalArgumentException();
 8     this.items = new Object[capacity];
 9     lock = new ReentrantLock(fair);
10     notEmpty = lock.newCondition();
11     notFull =  lock.newCondition();
12 }
13 
14 public ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c) {
15     this(capacity, fair);
16     // 加锁是为了保证可见性,因为可能存在其他线程在初始化之后修改集合。
17     final ReentrantLock lock = this.lock;
18     lock.lock();
19     try {
20         int i = 0;
21         try {
22             for (E e : c) {
23                 checkNotNull(e);
24                 items[i++] = e;
25             }
26         } catch (ArrayIndexOutOfBoundsException ex) {
27             throw new IllegalArgumentException();
28         }
29         count = i;
30         putIndex = (i == capacity) ? 0 : i;
31     } finally {
32         lock.unlock();
33     }
34 }

添加元素

ArrayBlockingQueue提供了offer()方法和put()方法两种方式添加元素。

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

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

 1 // 不允许被其他线程中断,添加失败则立即返回false。
 2 public boolean offer(E e) {
 3     checkNotNull(e);
 4     final ReentrantLock lock = this.lock;
 5     lock.lock();
 6     try {
 7         if (count == items.length)
 8             return false;
 9         else {
10             enqueue(e);
11             return true;
12         }
13     } finally {
14         lock.unlock();
15     }
16 }
17 
18 // 允许被其他线程中断,抛出InterruptedException,并且添加失败会等待。
19 public void put(E e) throws InterruptedException {
20     checkNotNull(e);
21     final ReentrantLock lock = this.lock;
22     lock.lockInterru
首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇消息中间件介绍(非原创) 下一篇RabbitMQ 消费端限流、TTL、死信..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目