Zdeněk Troníček wrote:
Ano, muze dochazet k prehozeni instrukci (muze to provest compilator, JIT, nebo
to muze byt dusledek cache). Toto je ovsem vyjimka. Viz specifikace na str.
322:

"Just before a reference to the newly created object is returned as the result,
the indicated constructor is processed to initialize the new object using the
following procedure: ..."
To samozrejme platit musi - spravne receno, JIT si muze instrukce prehazet jak chce, pokud to neovlivni beh programu. Specifikace nerika, jak ma fungovat JIT. Rika jak mate jeho fungovani vnimat. Ale nikde se tam nemluvi o tom, ze ten vysledek v pameti vidi i ostatni vlakna!
(http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.5)



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

V 1.4 nebylo dovoleno prohazovat pristupy k volatile promennym. Bylo ovsem mozne
prohazovat tyto pristupy s pristupy k non-volatile promennym.
Bylo dokonce mozne prehodit instrukce pred zapisem do volatile promene az za tento zapis. A nahodou to mohly byt i instrukce v konstruktoru - tj. nejdriv zapis pointeru na pamet na heapu do promene a az potom volani kodu konstruktoru (tedy double-check-locking nesel opravit pouzitim volatile).
Priklad z http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html:

class VolatileExample {
  int x = 0;
  volatile boolean v = false;
  public void writer() {
    x = 42;
    v = true;
  }

  public void reader() {
    if (v == true) {
      //uses x - guaranteed to see 42.
    }
  }
}

Jedno vlakno zavola writer() a druhe vlakno zavola reader(). Pokud vlakno v
metode reader() vidi v promenne v hodnotu true, v x bude 42. Je to tim, ze pri
zapisu do v v metode writer() dojde k zapisu hodnoty 42 do sdilene pameti
(jinak by tato hodnota mohla zustat v cache a nebyla by tudiz pro ostatni
vlakna viditelna).


Plati to i pro promenne inicializovane inicializatorem. Tj.
S tim souhlasim.
public class X {
  final double RATE = Math.random();
  ...
}

Pokud jde o pristup k finalni promenne, tak nevidim duvod, proc by nemel
fungovat getter.
Getter samozrejme fungovat bude.
Ale pokud inicializujete slozitejsi objekt a ulozite si referenci na nej do final i do nonfinal promene. A budete to cist stejnou z referenci z nonfinal promene, muzete ziskat nekonzistentni stav. Podobne kdyz pres getter ziskany slozity objekt predate do jineho vlakna.

Odpovedet emailem