Ahoj, podle me je to analogie s double checked locking u singletonu, takze mate pravdu, stat se to muze a jinak, nez synchronizovanim cele metody to neporesite.
Tady je to hezky vysvetlene: http://www.ibm.com/developerworks/library/j-dcl.html L. ________________________________________ From: [EMAIL PROTECTED] [EMAIL PROTECTED] On Behalf Of Jiri Dolezel [EMAIL PROTECTED] Sent: Thursday, September 06, 2007 2:00 PM To: [email protected] Subject: lazy-init cache a synchronizacni problem (double-check-locking) 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
