Недавно я столкнулся со странным поведением изменчивого ключевого слова. Насколько я знаю,
ключевое слово volatile применяется к переменной, чтобы отразить изменения, внесенные в данные переменной одним потоком в другой поток.
ключевое слово volatile предотвращает кэширование данных в потоке.
Я сделал небольшой тест ........
Я использовал целочисленную переменную с именем count и использовал для нее ключевое слово volatile.
Затем сделал 2 разных потока, чтобы увеличить значение переменной до 10000, поэтому конечный результат должен быть 20000.
Но это не всегда так, с изменчивым ключевым словом я получаю не постоянно 20000, а 18534, 15000 и т. Д., А иногда и 20000.
Но хотя я использовал синхронизированное ключевое слово, оно просто отлично работало, почему .... ??
Может кто-нибудь объяснить, пожалуйста, это поведение изменчивого ключевого слова.
Я публикую свой код с ключевым словом volatile, а также с кодом синхронизированного ключевого слова.
Следующий код ниже ведет себя несовместимо с ключевым словом volatile для счетчика переменных
public class SynVsVol implements Runnable{
volatile int count = 0;
public void go(){
for (int i=0 ; i<10000 ; i++){
count = count + 1;
}
}
@Override
public void run() {
go();
}
public static void main(String[] args){
SynVsVol s = new SynVsVol();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Total Count Value: "+s.count);
}
}
Следующий код отлично работает с синхронизированным ключевым словом в методе go (). [тысяча сто двадцать один]
public class SynVsVol implements Runnable{
int count = 0;
public synchronized void go(){
for (int i=0 ; i<10000 ; i++){
count = count + 1;
}
}
@Override
public void run() {
go();
}
public static void main(String[] args){
SynVsVol s = new SynVsVol();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Total Count Value: "+s.count);
}
}