Dobry den,
kdyz jedno vlakno priradi do volatile promenne a a druhe vlakno do
volatile promenne f, tak se prirazeni take nevykonaji paralelne, protoze
pristupy do pameti se (vetsinou) serializuji.
Navic nam je jedno, jak se to vykona. Dulezity (z hlediska ekvivalence) je
vysledek. A ten je v obou pripadech stejny.
Takze z tohoto pohledu jsou synchronized getter a setter a deklarace
volatile ekvivalentni.
Z.T.
--
Zdenek Tronicek
FIT CTU in Prague
Filip Jirsák napsal(a):
> Zdravím,
> ekvivalentní to určitě není. synchronized instanční metoda je ekvivalentní
> bloku synchronized(this) {…}, tj. ten setter odpovídá
>
> public void setF(int f) {
> synchronized(this) {
> this.f = f;
> }
> }
>
> Tj. pokud máte ty settery a gettery synchronizované, netýká se to jen
> operací uvnitř těch metod, ale bude to znamenat, že se všechna volání z
> různých vláken budou řadit za sebou. Tj. když z jednoho vlákna zavoláte
> setA() a z druhého setF(), nevykoná se to paralelně, ale popořadě. Já
> osobně se z tohohle důvodu synchronized metodám úplně vyhýbám, protože tam
> není na první pohled vidět, který objekt slouží jako zámek. A svádí to k
> představě, že jsou synchronizována jen volání té konkrétní metody.
>
> S pozdravem
>
> Filip Jirsák
>
>
> Dne 13. června 2012 10:59 Libor Jelinek <[email protected]> napsal(a):
>
>> Aaaa! Pravda! Synchronized vlastně mj. nastavuje i happens-before vztah.
>>
>> Podotázka k setteru: Kdybych z nějakého prapodivného důvodu nechtěl mít
>> setter setter metodu jako synchronized, bylo by ekvivalentní nastavované
>> pole označit jako volatile, že?
>>
>> Zbývající otázka: Je "return f" v getteru atomická operace nebo není?
>>
>>
>> 2012/6/13 Peter Štibraný <[email protected]>
>>
>>> Dobry den,
>>>
>>> problem nie je s atomicitou operacie, ale s tym, aby tato zmena (zapis
>>> do
>>> premennej) bola viditelna v inych threadoch. Ak takuto viditelnost
>>> potrebujete, tak potrebujete nejaku formu synchronizacie. Ak tam ziadnu
>>> synchronizaciu mat nebudete, tak sa moze stat ze ine thready uvidia
>>> staru
>>> hodnotu.
>>>
>>> -Peter
>>>
>>>
>>> On Wednesday, 13. June 2012 at 10:34, Libor Jelinek wrote:
>>>
>>> > DD,
>>> > často při čtení kódu (ale i učebnicích) narážím na něco jako toto:
>>> >
>>> > class A {
>>> > private int f;
>>> > public synchronized int getF() { return f };
>>> > public synchronized void setF(int f) { this.f = f };
>>> > }
>>> >
>>> > Podle JLS je atomické jednoduché čtení/zápis referečnní proměnné a
>>> primitives krom long a double (pokud nejsou volatile). Nehrozí tedy u
>>> nich
>>> žádné interleaving (přerušení v půlce).
>>> >
>>> > To, myslím, beze zbytku platí pro setF(), kdy se jedná o jednoduché
>>> nastavení, a tedy nemusí být synchronized.
>>> >
>>> > U getF() jsou to možná dvě operace (instrukce) pro JVM (přečíst a
>>> vrátit), ale nejsem si jistý, a proto v tomto případě taky raději
>>> synchonizuju...
>>> >
>>> > Chci se tedy zeptat, jestli je tedy u setF() synchronizace opravdu
>>> zbytečná. A jak je to s getF(), zda je to atomická operace a také není
>>> nutné synchronizovat.
>>> >
>>> > Díky
>>> > Libor
>>>
>>>
>>>
>>>
>>
>