我正在閱讀有關哈希表的問題,這個問題讓我感到震驚。哈希表是同步的,所以Hashtable中的迭代器是否可以進行故障安全?哈希表中的併發和故障安全行爲
此外,對於故障安全集合,當多個線程嘗試訪問集合時,您將不會收到ConcurrentModificationException,因爲每個線程都在自己的副本上工作。我想知道這是否意味着每個線程的內存中都創建了Collection的實際物理副本?
我正在閱讀有關哈希表的問題,這個問題讓我感到震驚。哈希表是同步的,所以Hashtable中的迭代器是否可以進行故障安全?哈希表中的併發和故障安全行爲
此外,對於故障安全集合,當多個線程嘗試訪問集合時,您將不會收到ConcurrentModificationException,因爲每個線程都在自己的副本上工作。我想知道這是否意味着每個線程的內存中都創建了Collection的實際物理副本?
嗯......如果「故障安全」你的意思是你不能得到一個ConcurrentModificationException
,那麼那麼答案是否定的,您可以當你就可以使用Iterator
得到一個Hashtable
該異常。 javadoc明確指出。
此外,對於故障安全的集合,當多個線程試圖訪問一個集合,你會不會因爲每個線程正在其自身的副本,它得到一個ConcurrentModificationException的。
(你似乎引用或總結,從地方。無論如何,我不認爲這是正確的。)
我不知道這是否意味着,這的一個實際的物理拷貝集合是在每個線程的內存中創建的?
在某些情況下,迭代器正在處理一個不會被修改的副本。在其他情況下,迭代器正在處理可能會被修改和/或根本不代表集合的一致快照的事情。這實際上取決於如何爲您正在討論的特定集合類指定「故障安全」行爲。 (和對集合類的好東西之一是,他們明確規定,你可以和不可以靠的是什麼。你只需要仔細閱讀說明書以確保你真正瞭解他們!)
哦,所以Hashtable中的迭代器是快速失敗的,但枚舉器是自動防故障的。
第一部分是正確的。第二個是不正確的。
由Hashtable
返回的Enumeration
對象不保證是故障安全的。 javadocs的狀態是Enumeration
不是快速故障。當您修改Hashtable
並同時枚舉它時實際發生的是未指定。 (如果您真的想知道,請查看您正在使用的特定Java版本的源代碼。)
RTFM:
由所有此類的「collection視圖方法」返回的collection的iterator方法返回的迭代器是快速失敗的:如果Hashtable是在任何時間後的結構修飾除了通過迭代器自己的remove方法以外,任何方式都會創建迭代器,迭代器將拋出ConcurrentModificationException異常。因此,面對併發修改,迭代器快速而乾淨地失敗,而不是在將來某個未確定的時間冒着任意的,非確定性的行爲風險。 Hashtable的鍵和元素方法返回的枚舉不是快速失敗的。
請注意,迭代器的故障快速行爲無法得到保證,因爲一般來說,在出現非同步併發修改時不可能做出任何硬性保證。失敗快速迭代器盡最大努力拋出ConcurrentModificationException。因此,編寫一個依賴於此異常的程序是正確的:迭代器的快速失敗行爲應僅用於檢測錯誤。
換句話說,迭代通過Hashtable
不大於迭代過非同步HashMap
更安全。
請養成添加相關語言標籤的習慣。 – 2013-04-25 02:37:04
當然,對不起。 – Setafire 2013-04-25 02:41:37
只是澄清,ConcurrentModificationException(儘管它的名稱)_really與threads_無關。線程安全和「修改安全期間的迭代」(CME)是兩個正交的概念。 – jtahlborn 2013-04-25 03:35:04