Nejprve si musíte určit, co vlastně znamená, že se jedná o ten samý objekt. Ale pokud vám z toho vyjde, že jeden objekt (konkrétní místo v paměti) může v průběhu své životnosti představovat několik různých objektů (hashCode a equals zahrnují položky, které se mohou změnit), nebude vám to s většinou kolekcí fungovat.
Tohle ale s vícevláknovým přístupem nesouvisí. Vám ten vícevláknový přístup nejspíš rozbil vnitřní implementaci HashMapy použitou v tom LinkedHashSetu. To by modifikovatelné prvky kolekce nezpůsobily, ty by mohly způsobit nanejvýš to, že byste do kolekce nějaký prvek vložil, ale on by tam později nebyl, nebo byste do kolekce vložil prvek, ale později byste tam našel jiný.
Ano, akorát s tím vícevláknovým přístupem to přece jen asi trochu souvisí, i když volně - a to tak, že pokud sdílím takhle napříč aplikací objekty, je větší šance, že budou někde modifikovány (kvantitativní, nikoli kvalitativní souvislost).
Modifikace se položek se nicméně děje zcela vyjimečně a věřím, že framework implementuje equals, hashCode a compareTo rozumně (konkrétně identitu dělá podle UUID objektu a compare podle řadící anotace, hashCode teď nevím). Kolekce fungují a nanejvýš můžu mít v setu chvíli neaktualizovanou položku, což mi nevadí.
Mně teda ale hlavně překvapuje, pokud tam Ondřej ty iterátory normálně používá, že to nikdy nevypadlo na ConcurrentModificationException. Že je to jenom taková nouzová pojistka, která ve vícevláknovém prostředí nemusí fungovat správně, je jasné, ale že se to netrefilo nikdy… Předpokládám, že modifikace toho setu probíhala z jiných vláken, než která používala ten iterátor, takže prostě každé vlákno mělo svou lokální hodnotu počtu modifikací a nikdy se to nepotkalo.
Já sám iterátory v kódu přímo nepoužívám (mimo toho testovacího, který jsem zkopíroval z interaktivní vývojové konzole). Ten set je bokem mimo framework jen proto, abych z jiné větší kolekce, kterou framework již normálně managuje, vybral část a uložil do toho setu bokem. Z něho pak po jedné odebírám položky a když položky dojdou, tak to zopakuju a zase jej naplním. Pokud se zdrojová kolekce změní, provede se merge položek - položky odstraněné ze zdrojové kolekce zmizí i ze setu. LinkedHashSet je tam proto, aby tam byla každá položka jen jednou a pamatovalo se pořadí vložení. Operace nad setem jsou tedy remove(), clear() a add() bez použití iterátoru.
tady ale nebyl problém s prvky té kolekce, ale s tou kolekcí jako takovou.
Je to tak, skutečně se ten set dostal do nekonzistentního stavu - protože není thread safe a nezajistil jsem správnou synchronizaci. Původně jsem spíš myslel že bude problém v identitě prvků setu ale nakonec jsem s jistotou ověřil, že to je v té synchronizaci.