2013-03-10 100 views
1

我正在寫一個2線程的程序。一個迭代循環鏈表。該列表總是有下一個元素,因爲鏈表是循環的。另一個線程修改列表。但我得到concurrentModificationException。 我能用它做什麼? 由於同步循環鏈表

+3

一點代碼在這裏會有所幫助。 – 2013-03-10 05:06:51

+0

你使用的是什麼樣的鏈表? – angelatlarge 2013-03-10 05:07:04

+0

這是java.util包中的java鏈接列表(這是一個循環鏈表) – dev 2013-03-10 06:06:11

回答

0

假設你的實現是線程安全的(你使用哪個類?)迭代器本質上不是線程安全的。它們不在列表上保持鎖定,因此它們不能讓其他線程修改它。

如果您CircularList本身同步(不知道你使用的是什麼,但它是線程安全的列出了常見的 - 否則,迭代器將基本上一直都是非線程),就可以解決這個做:

synchronized(list) { 
    Iterator i = list.iterator(); 
    doSomething(i); 
} 

另請參閱: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collections.html#synchronizedList(java.util.List)

+0

因爲鏈表是循環的並且總是存在一個迭代的下一個節點,所以這個同步塊不會釋放該列表並且另一個線程總是處於等待模式! – dev 2013-03-10 06:48:54

0

從以下API文檔:

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/ConcurrentModificationException.html

此異常可能由已檢測出的對象的併發修改時這種修改是不允許的方法被拋出。

例如,一個線程在另一個線程遍歷它時修改一個集合通常是不允許的。一般來說,在這些情況下迭代的結果是不確定的。某些迭代器實現(包括由JRE提供的所有通用集合實現的實現)可能會選擇在檢測到此行爲時拋出此異常。這樣做的迭代器被稱爲快速迭代器,因爲它們快速且乾淨地失敗,而在將來未定的時間冒着任意的,非確定性的行爲冒險。

請注意,此異常並不總是表示某個對象已被另一個線程同時修改。如果單個線程發出違反對象合約的一系列方法調用,則該對象可能會拋出此異常。例如,如果一個線程在使用快速迭代器迭代集合的同時直接修改集合,迭代器將拋出此異常。

+0

我已經閱讀過這個文檔。但我正在尋找一些解決方案。 – dev 2013-03-10 06:14:23

+0

爲此,您需要顯示代碼。 – 2013-03-10 07:12:04

0

在這種情況下不要使用迭代器,因爲這是異常來自的地方。

通過簡單地設置currentElement = currentElement.next()或任何在您的(無限?)循環中調用的元素來推進當前元素。

如果列表不是線程安全的,那麼在修改數據結構時可能會遇到麻煩。

+0

我在java.util包中使用linkedlist類,因此無法直接訪問currentelement而無需迭代器。 – dev 2013-03-10 06:09:58

+0

循環是一個無限循環,因爲鏈表是循環的 – dev 2013-03-10 06:10:48