Zdeněk Troníček wrote:
Ahoj,

k situaci "PROBLEM" od verze 1.5 dojit nemuze. Drive to mozne bylo, ale od 1.5
ma Java "vylepseny" pametovy model a ten zarucuje, ze v okamziku, kdy new vrati
referenci, je objekt inicializovany (tj. probehl jeho konstruktor).
Todle prave v 1.5 neplati! Instrukce se porad muzou libovolne prehazet :-)
Instrukce se nemuzou prehazovat pres zapis do volatile nebo prechod pres synchronizovanou sekci (tj. ostatni vlakna vidi, ze vsechno je provedeno pred vstupem do synchronizovane sekce / zapisem do volatile).

V 1.4 a driv vyse uvedene neplatilo prave pro volatile. A neslo tedy double-check-locking opravit nastavenim te promene na volatile.

Je vsak mozne neco jineho (mapa je sdilena promenna typu Map):

class Trida {
  int x;
  Trida(int x) {
    this.x = x;
  }
}

Vlakno 1:
Trida p = new Trida(42);
mapa.put("odpoved", p);

Vlakno 2:
Trida p = mapa.get("odpoved");

Pokud Vlakno 2 dostane referenci na objekt vytvoreny vlaknem 1, muze se stat, ze
 v promenne x uvidi hodnotu 0 (defaultni hodnotu). Je to tim, ze program neni
spravne synchronizovan (mezi zapisem do x a ctenim x neni definovan
synchronizacni bod). Vlakno 1 totiz muze mit hodnotu 42 v cache a nemusi ji
okamzite zapsat do sdilene pameti (cache nemusi byt skutecna cache, ale treba
jen registr).

Je-li toto problem, lze to resit zavedenim synchronizacnich bodu nebo
jednoduseji pouzitim modifikatoru final ci volatile. Pokud by promenna x byla
final, bude jeji hodnota vzdy viditelna v ostatnich vlaknech.
Toto plati (pouze) pro final promene inicializovane v konstruktoru. A na ty hodnoty musi to druhe vlakno pristupovat pres tu final promenou. Pricemz tato vlastnost je tranzitivni.
Jinak misto Collections.synchronizedMap(...) je lepsi ConcurrentHashMap, ktera
povoluje soubezne cteni.

Z.T.

Odpovedet emailem