Почему Volatile ведет себя странно

Недавно я столкнулся со странным поведением изменчивого ключевого слова. Насколько я знаю,

  1. ключевое слово volatile применяется к переменной, чтобы отразить изменения, внесенные в данные переменной одним потоком в другой поток.

  2. ключевое слово volatile предотвращает кэширование данных в потоке.

Я сделал небольшой тест ........

  1. Я использовал целочисленную переменную с именем count и использовал для нее ключевое слово volatile.

  2. Затем сделал 2 разных потока, чтобы увеличить значение переменной до 10000, поэтому конечный результат должен быть 20000.

  3. Но это не всегда так, с изменчивым ключевым словом я получаю не постоянно 20000, а 18534, 15000 и т. Д., А иногда и 20000.

  4. Но хотя я использовал синхронизированное ключевое слово, оно просто отлично работало, почему .... ??

Может кто-нибудь объяснить, пожалуйста, это поведение изменчивого ключевого слова.

Я публикую свой код с ключевым словом 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);
    }
}
8
задан Marko Topolnik 1 July 2012 в 10:56
поделиться