簡體   English   中英

同步集合中的ConcurrentModificationException

[英]ConcurrentModificationException in synchronized collection

我正在使用SynchronizedCollection.containsAll面臨的問題是,當我運行以下代碼時,我遇到了ConcurrentModification Exception

根據我的理解,代碼應該毫無例外地終止。

public class Main {

    public static void main(String[] args) {
        List l1 = new LinkedList(), l2 = new LinkedList();
        for (int i = 0; i < 100000; i++) {
            l1.add("" + i);
        }
        for (int i = 0; i < 100000; i++) {
            l2.add("" + i);
        }
        // reverse to make the search take a little longer
        Collections.reverse(l2);
        final List sl1 = Collections.synchronizedList(l1);
        final List sl2 = Collections.synchronizedList(l2);

        new Thread() {
            public void run() {
                // synchronized (sl2) {
                sl1.containsAll(sl2);
                // }
            }
        }.start();
        new Thread() {
            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
                sl2.add("3");
            }
        }.start();
    }

}

有人可以幫我理解為什么我得到這個例外。

根據Collections::synchronizedList的文檔

當用戶遍歷返回列表時,必須手動對其進行同步。

在您的例子,當你運行sl.containsAll(sl2)你遍歷sl2不上同步sl2 誠然, 這是 containsAll方法的實現細節,但在javadoc中已明確指出

此實現迭代指定的集合,依次檢查迭代器返回的每個元素以查看其是否包含在此集合中。

您可以通過在sl2同步來解決問題(即,取消注釋已注釋掉的代碼)。

我檢查了代碼,我認為異常是有意的,但是如果當前代碼

public boolean containsAll(Collection<?> coll) {
synchronized(mutex) {return c.containsAll(coll);}
        }

更改為...。

public boolean containsAll(Collection<?> coll) {
synchronized(mutex) {
               synchronized(coll) {
              return c.containsAll(coll);}}
        }

然后問題將得到解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM