Java多線程與並發庫進階應用程式-同步集合

來源:互聯網
上載者:User

標籤:mod   locking   index   介紹   else   list   expected   one   test   

ArrayBlockingQueue

LinkedBlockingQueue

數組是連續的一片記憶體

鏈表是不連續的一片記憶體

 傳統方式下用Collections工具類提供的synchronizedCollection方法來獲得同步集合。

java5中提供了如下一些同步集合類:

  > 通過看java.util.concurrent包下的介紹可以知道有哪些並發集合

  > ConcurrentHashMap

  > CopyOnWriteArrayList

  > CopyOnWriteArraySet

傳統方式下的Collection在迭代時,不允許對集合進行修改。

使用Iterator對集合進行迭代時不能修改集合

 

public class CollectionModifyExceptionTest {    public static void main(String[] args) {        List<String> strs = new ArrayList<>();        strs.add("aaa");        strs.add("bbb");        strs.add("ccc");        Iterator iterator = strs.iterator();        while(iterator.hasNext()){            System.out.println(".....");            String value = (String)iterator.next();            if("aaa".equals(value)){                strs.remove(value);            }else{                System.out.println(value);            }        }    }}

以上代碼在遍曆集合時,對集合進行修改,會拋出異常

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at com.java.thread.CollectionModifyExceptionTest.main(CollectionModifyExceptionTest.java:17)

異常拋在這一句 

String value = (String)iterator.next();
/**     * An optimized version of AbstractList.Itr     */    private class Itr implements Iterator<E> {        int cursor;       // index of next element to return        int lastRet = -1; // index of last element returned; -1 if no such        int expectedModCount = modCount;        public boolean hasNext() { //            return cursor != size;        }        @SuppressWarnings("unchecked")        public E next() {            checkForComodification();            int i = cursor;            if (i >= size)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i + 1;            return (E) elementData[lastRet = i];        }        public void remove() {            if (lastRet < 0)                throw new IllegalStateException();            checkForComodification();            try {                ArrayList.this.remove(lastRet);                cursor = lastRet;                lastRet = -1;                expectedModCount = modCount;            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }        final void checkForComodification() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();//此處拋異常        }    }

 

 

然而在將"aaa" 改成"bbb"時,卻沒有拋出異常

因為在遍曆到 bbb 時,cursor為1(0,1,2),將 bbb 移除後size為2 進行下次遍曆是cursor為 2

所以hasNext()返回的為false 就不會進入迴圈。

 

要解決這個問題,可以使用 CopyOnWriteArrayList  在寫的時候有一份拷貝,

public static void main(String[] args) {        List<String> strs = new CopyOnWriteArrayList();        strs.add("aaa");        strs.add("bbb");        strs.add("ccc");        Iterator iterator = strs.iterator();        while(iterator.hasNext()){            System.out.println(".....");            String value = (String)iterator.next();            if("aaa".equals(value)){                strs.remove(value);            }else{                System.out.println(value);            }        }    }

 

Java多線程與並發庫進階應用程式-同步集合

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.