前面我们介绍了CopyOnWriteArrayList,今天我们来介绍一下CopyOnWriteArraySet,非常有意思的是CopyOnWriteArraySet是基于CopyOnWriteArrayList实现的,有兴趣的同学可以翻看一下我上一篇关于CopyOnWriteArrayList的博客。
介绍
/**
* A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList}
* for all of its operations. Thus, it shares the same basic properties:
* <ul>
* <li>It is best suited for applications in which set sizes generally
* stay small, read-only operations
* vastly outnumber mutative operations, and you need
* to prevent interference among threads during traversal.
* <li>It is thread-safe.
* <li>Mutative operations ({@code add}, {@code set}, {@code remove}, etc.)
* are expensive since they usually entail copying the entire underlying
* array.
* <li>Iterators do not support the mutative {@code remove} operation.
* <li>Traversal via iterators is fast and cannot encounter
* interference from other threads. Iterators rely on
* unchanging snapshots of the array at the time the iterators were
* constructed.
* </ul>
*
* <p><b>Sample Usage.</b> The following code sketch uses a
* copy-on-write set to maintain a set of Handler objects that
* perform some action upon state updates.
*
* <pre> {@code
* class Handler { void handle(); ... }
*
* class X {
* private final CopyOnWriteArraySet<Handler> handlers
* = new CopyOnWriteArraySet<Handler>();
* public void addHandler(Handler h) { handlers.add(h); }
*
* private long internalState;
* private synchronized void changeState() { internalState = ...; }
*
* public void update() {
* changeState();
* for (Handler handler : handlers)
* handler.handle();
* }
* }}</pre>
*
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @see CopyOnWriteArrayList
* @since 1.5
* @author Doug Lea
* @param <E> the type of elements held in this collection
*/
我直接翻译了哈,这个set呢是用了一个内部的CopyOnWriteArrayList用于她所有的操作。所以呢这个set 享有和CopyOnWriteArrayList一样的属性。
成员属性
private final CopyOnWriteArrayList<E> al;
/**
* Creates an empty set.
*/
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}
显然哈,内部就是这个一个CopyOnWriteArrayList,甚至在实现的时候直接new一个出来,就是这么直接。
成员方法
新增
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element {@code e} to this set if
* the set contains no element {@code e2} such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns {@code false}.
*
* @param e element to be added to this set
* @return {@code true} if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return al.addIfAbsent(e);
}
看到代码大家都应该明白了,他就是判断一下这个元素在列表中是否存在,如果不存在则添加到这个集合中;我们来喵一下这个addIfAbsent是怎么实现的
/**
* Appends the element, if not present.
*
* @param e element to be added to this list, if absent
* @return {@code true} if the element was added
*/
public boolean addIfAbsent(E e) {
Object[] snapshot = getArray();
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
}
/**
* A version of addIfAbsent using the strong hint that given
* recent snapshot does not contain e.
*/
private boolean addIfAbsent(E e, Object[] snapshot) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] current = getArray();
int len = current.length;
if (snapshot != current) {
// Optimize for lost race to another addXXX operation
int common = Math.min(snapshot.length, len);
for (int i = 0; i < common; i++)
if (current[i] != snapshot[i] && eq(e, current[i]))
return false;
if (indexOf(e, current, common, len) >= 0)
return false;
}
Object[] newElements = Arrays.copyOf(current, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
上面这个addIfAbsent都是CopyOnWriteArrayList的哈,大致意思就是判断一下这个元素在这个数组里面在不在,如果不在就创建一个新的数组,拷贝原来的数组元素,然后吧这个数放到数组的最后一个位置,当然这中操作都是需要线程安全的哈。
删除
/**
* Removes the specified element from this set if it is present.
* More formally, removes an element {@code e} such that
* <tt>(o==null ? e==null : o.equals(e))</tt>,
* if this set contains such an element. Returns {@code true} if
* this set contained the element (or equivalently, if this set
* changed as a result of the call). (This set will not contain the
* element once the call returns.)
*
* @param o object to be removed from this set, if present
* @return {@code true} if this set contained the specified element
*/
public boolean remove(Object o) {
return al.remove(o);
}
删除没啥好说的哈,就是调用CopyOnWriteArrayList的删除
最后
废话说了这么多,总结一下:其实也没啥好总结的,就是CopyOnWriteArrayList然后去重了,其他基本一致。
最后大家猜一下,他每次迭代的结果一致(有序)吗?
本文深入探讨了CopyOnWriteArraySet的实现原理,它基于CopyOnWriteArrayList并实现了线程安全的Set功能。文章详细解释了其成员属性、新增与删除等核心操作的实现细节。
2333

被折叠的 条评论
为什么被折叠?



