Získám tím sdílený stav.
Získáte tím stav sdílený mezi jedním singletonem. To je trošku nesmysl, ne? A je to přesně to, co vás vypeklo – že jste jeden singleton měl z poloviny udělaný jedním způsobem a z poloviny druhým.
Ano, proto by skutečně dávalo smysl tu funkčnost vytáhnout bokem jak uvádí Zdenek Henek Tam bych si mohl i sám řešit, zda to je tvrdý singleton nebo ne - aniž by na to měl vliv framework (tj. bylo by to vyčlenění kompetence). Co mi ještě není úplně jasné je, čemu se vystavuju, pokud bych vracel ven měnitelné položky toho setu (neobalil je jak uvádí Zdenek Henek)? Pokud se podívám, jak framework implementuje hashCode, compareTo a equals, neměl bych v kolekcích ani při modifikaci narazit na problém. Je to tak? Resp. se to asi dočtu v té kapitole Publication and escape v Java Concurrency in Practice.
Pokud mate synchronizovane oprace nad Set<...> tak to nestaci pokud neco co je v te Set pustite mimo synchronized sekci a pak to tam menite. Musite zajistit, ze se to bud nebude menit - nejlepsi, nebo ze veskere zmeny budou opet synchronizovane.
Jestli muzu doporucit, poridte si tu knihu Java Concurrency in practice. Nebojte se, ze je z roku 2006, jedine, co tam nenajdete jsou nove veci implementovane pozdeji, ale zakladni princip Vasi otazky tam je moc dobre popsany.
Pochybuju ze objectk Image je immutable, pokud je, tak nemusite nic delat. Immutable, znamena, ze bez reflexe se s tim neda nic delat, ne ze si slibite, ze to nebudete menit, protoze na to zapomenete. Jeste muzete pred kazdou modifikaci udelat clon toho objektu a po provedeni zmen vyhodit ze Set objektu ten stary a dat tam novy ... , ale to je cesta do pekel. Pak je clone na kazdem rohu.
Nejjednodussi pravidlo je, ze cokoli je sdilene je immutable a ma to builder. Pokud to nejde, tak wrapper a synchronizace.