Przeczytałem "Zrozumienie zaawansowanych funkcji i najlepszych praktyk JVM", który zawiera segment kodu, który wyjaśnia dzieje - przed regułą w java. Nie rozumiem. Kod jest poniżej:, jeśli wątek A rozpoczyna się przed wątkiem B w języku Java, to A zostanie zaplanowane przez os przed B?
private int value = 0;
//executed by Thread A
public void setValue(int value){
this.value = value;
}
//executed by Thread B
public void getValue(){
return value;
}
Załóżmy, że gwint A
starty przed wątku B
w kodzie. Rozumiem, że nie znamy wyniku zwróconego przez getValue()
w wątku B, ponieważ nie jest bezpieczny dla wątków. Ale książka mówi, czy dodać zsynchronizowane słowo kluczowe do funkcji setValue()
i getValue()
, to nie istnieje problem bezpieczny wątek i metoda zwróci właściwą wartość. Książka wyjaśnia, że ponieważ synchronized
spotyka się z dzieje się przed reguły. Mam więc dwa pytania poniżej kodu.
public class VolatileDemo3 {
private volatile int value = 0;
public static void main(String[] args) {
VolatileDemo3 v = new VolatileDemo3();
Thread A = new Thread(v.new Test1());// Thread A
Thread B = new Thread(v.new Test2());//Thread B
A.start();
B.start();
}
public void setValue(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
public class Test1 implements Runnable {
@Override
public void run() {
setValue(10);
}
}
public class Test2 implements Runnable {
@Override
public void run() {
int v = getValue();
System.out.println(v);
}
}
}
- Chociaż
A.start()
prowadzony przedB.start()
i wartości jestvolatile
, nie możemy zapewnić gwint B może wydrukować10
, prawda? Ponieważ wątek B jest możliwe zaplanowane najpierw przez JVM, a następnie wątek B będzie drukować 0 nie 10. - Nawet jeśli wątek
A
zaplanowane przed wątkuB
przez JVM, ale również nie może zagwarantować, że instrukcjathis.value = value
realizowane przez JVM ponieważ przedreturn this.value
JVM będzie ponownie sortować instrukcje. Czy zrozumienie jest słuszne? Proszę pomóż mi.
Istnieje różnica między "bezpiecznym wątkiem" i "przewidywalnym". Dodanie opcji 'zsynchronizowany' będzie oznaczać, że wątek B zawsze będzie wyświetlał wartość' prawidłowość_ ', ale może jeszcze nie zostać zaktualizowana. Jak podkreślasz, nie ma gwarancji, że te dwa wątki będą wykonywane w założonej kolejności. Bez 'zsynchronizowanej 'nie ma gwarancji _visibility_, więc nawet jeśli A zostanie wykonane najpierw, B może nadal widzieć starą" wartość ". –
Myślę, że źle czytasz. Jeśli istnieje słowo kluczowe "zsynchronizowane", oznacza to, że JVM zagwarantuje, że w danym momencie nie można mieć dwóch wątków wykonujących jednocześnie "setValue" i "getValue" (jeden będzie musiał zakończyć wykonywanie metody przed inny wątek może wprowadzić inną metodę). Nie * nie * gwarantuje niczego na temat kolejności tych operacji. – Paolo
Aby zapewnić "poprawną" widoczność, należy zadeklarować 'private volatile int value = 0;'. To sprawia, że napisana wartość jest widoczna po wszystkich pozostałych wątkach. – PeterMmm