CopyOnWriteArrayList的addIfAbsent()方法
生活随笔
收集整理的這篇文章主要介紹了
CopyOnWriteArrayList的addIfAbsent()方法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?大致執(zhí)行過程:首先獲取當(dāng)前數(shù)組存取元素,然后找我們要插入數(shù)據(jù)的下標(biāo)值,找到了直接返回false,沒找到的話,上鎖,再次判斷數(shù)組是否發(fā)生變化,這里多一次判斷,我認(rèn)為是為了防止這種可能性的出現(xiàn):在判斷完是否存在元素和加鎖之間,另一個線程加入了我們要加的元素,不判斷的話,那么同一個元素就有可能出現(xiàn)倆次,違背了addIfAbsent的意愿。加鎖之后,如果數(shù)組并沒有變的話,那么就執(zhí)行CopyOnWriteArrayList的老套路,將原來的數(shù)據(jù)放到一個比原來長度長1的數(shù)組,最后一個空位放我們要放的數(shù)據(jù)。通過上述過程就實現(xiàn)了數(shù)據(jù)的唯一性,CopyOnWriteSet底層實現(xiàn)就是利用CopyOnWriteArrayList,唯一性就是利用addifabsent方法。
public boolean addIfAbsent(E e) {// 獲取元素數(shù)組, 取名為快照Object[] snapshot = getArray();// 檢查如果元素不存在,直接返回false// 如果存在再調(diào)用addIfAbsent()方法添加元素return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :addIfAbsent(e, snapshot); }private boolean addIfAbsent(E e, Object[] snapshot) {final ReentrantLock lock = this.lock;// 加鎖lock.lock();try {// 重新獲取舊數(shù)組Object[] current = getArray();int len = current.length;// 如果快照與剛獲取的數(shù)組不一致// 說明有修改if (snapshot != current) {// 重新檢查元素是否在剛獲取的數(shù)組里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;}// 拷貝一份n+1的數(shù)組Object[] newElements = Arrays.copyOf(current, len + 1);// 將元素放在最后一位newElements[len] = e;setArray(newElements);return true;} finally {// 釋放鎖lock.unlock();} }總結(jié)
以上是生活随笔為你收集整理的CopyOnWriteArrayList的addIfAbsent()方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大话ConcurrentHashMap的
- 下一篇: 几个需要扩容的集合