Ahoj,
i) to Lukas M.:
Ten clanek (http://www.ibm.com/developerworks/library/j-dcl.html) znam, jenze -
podobne jako vsechny ostatni, ktere jsem prosel - se zabyvaji singletonama. Z
toho prameni moje nejistota, protoze to je prece jen trochu jiny pripad... v
pripade singletonu nas zajima singleton jako takovy, v mem pripade nas zajimaji
jine objekty, ktere dana mapa pouze agreguje.
ii) to Roman:
Zajimavy tip; po prostudovani javadocu to na me pusobi tak, ze pouziti
ConcurrentHashMap bude mit i pozitivni vykonnostni dopady, protoze operace
cteni jsou neblokujici a poskytuji vzdy posledni konzistentni vysledky zapisu.
Koneckoncu i sam Doug Lea rika, ze ConcurrentHashMap byla zamyslena jako plna
nahrada Hashtable. Nadruhou stranu jsem nikde nenasel, ze by to resilo uvedeny
problem, coz ovsem neznamena, ze tomu tak neni - nemate nejaky "vysvetlujici"
odkaz?
iii) to Lukas B.:
Tak to je prave to, cim si nejsem jisty. Mas pravdu, ze set/get jsou vzajemne
synchronizovane, coz zaruci vzajemne blokovani cteni a zapisu. Dokonce mame i
zaruceno, ze je kazdy Produkt vytvoren prave jednou. Ale je zaruceno to, ze se
nekonzistentni produkt nedostane do jineho vlakna? Viz uvedeny priklad, kdy
vlakno A ulozi nekonzistentni objekt do mapy a pak je preruseno. Podle me to
zaruceno neni, protoze to by musely byt soucasne definovany prvky mapy jako
volatile.
Jinak diky za zajimavy napad s dalsim urychlenim. V mem pripade to vsak nema
vyznam, protoze produkty se incializuji jednou a pak se uz se jen ctou - a ta
trocha blokovani na zacatku nas nezabije :-)
Diky vsem,
Jirka
>Ahoj,
>
> uvedeny kod je spravne i pro viceprocesorove stroje.
> Situace popsana v 1 nastat nemuze protoze kazdy zapis a cteni z
>cacheOfProducts je synchronizovane (synchronizedMap) - tj. cteni zde po
>zapisu vzdy pres synchronized. (put happens before get)
> A pri vytvareni nove hodnoty synchronizuji vsechny vlanka pres
>cacheOfProcuts, takze kazdy produkt je vytvoren prave jednou.
>
>Pokud byste ten kod chtel jeste vice zrychlit (pokud soucasne prijde
>vice vlaken s pozadavkem na ruzny produkt budou na sebe cekat na
>cacheOfProducts), muzete zacit synchronizovat na nejakem wrapperu
>Stringu vytvorenem stejnym zpusobem jako produkt (to ma smysl pouze
>pokud new Produkt(name) muze byt hodne pomale - napr. cteni z DB). ;-)
>
> Lukas
>
>
>Jiri Dolezel wrote:
>> Ahoj,
>> pracuji s JEE aplikaci provozovanou na viceprocesorovem stroji (Java 5), kde
>> se casto pouzivaji konstrukce tohoto typu:
>>
>> **** zacatek prikladu ****
>>
>> class ProductsCache {
>> // staticka cache: "nazev produktu" -> "DTO produktu"
>> private static final Map<String,Product> cacheOfProducts
>> = Collections.synchronizedMap(new HashMap<String,Product>());
>>
>> public Product get(String name) {
>> // nejdrive jej zkusime najit v cache
>> Product product = cacheOfProducts.get(name);
>>
>> if (product == null) {
>> // pokud v cache neni, vytvor jej v synchronizovanem bloku
>> synchronized (cacheOfProducts) {
>> // "double-checked-locking"?
>> product = cacheOfProducts.get(name);
>>
>> if (product == null) {
>> // PROBLEM: Muze se nam stat, ze se neuplne
>> inicializovany produkt ulozi do cache
>> // a jine vlakno tak ziska nekonzistentni produkt?
>> product = new Product(name);
>> cacheOfProducts.put(name, product);
>> }
>>
>> }
>> }
>>
>> return product;
>> }
>> }
>>
>> **** konec prikladu ****
>>
>> Mam k tomuto kodu dve otazky:
>> 1) Muze skutecne dojit k situaci popsane v kodu jako "PROBLEM"? Podle me
>> ano, pokud prekladac/CPU prohodi instrukce takto:
>> - (vlakno A) vytvor novy objekt Produkt "nazev"
>> - (vlakno A) proved cacheOfProducts.put("nazev", product);
>> - (vlakno B) zavolej cacheOfProducts.get("nazev") => ziska nekonzistentni
>> produkt
>> - (vlakno A) dokonci inicializaci produktu "nazev"
>>
>> 2) Pokud skutecne muze nastat situace 1), nabizi Java 5 moznost, jak tomu
>> predejit, aniz bychom synchronizovali celou metodu get()?
>>
>> Zkoumal jsem pouziti volatile za timto ucelem (tzn. deklarovat
>> cacheOfProducts jako volatile), ale to se vylucuje s final.
>> Ikdyby vsak cacheOfProducts nebylo final, resilo by volatile tento problem?
>> Ve specifikaci se uvadi, ze prvky pole, ktere je deklarovane jako volatile,
>> samy volatile nejsou. A jelikoz kolekce je postavena na polich, tak si
>> myslim, ze to problem opet neresi. Ale to jsou jen me dohady.
>>
>> Prosim, pokud do toho vidite, vysvetlete mi cely problem jednou provzdy :-)
>>
>> Jirka
>>