2015-03-30 5 views
0

Я пытаюсь написать простой код, чтобы понять volatile ключевое слово в java.Ошибка volatile ключевого слова в java

Идея состоит в том, чтобы увеличить значение count Поле класса Runner с использованием двух потоков. Класс помощника реализует Runnable, где метод запуска увеличивает значение , которые оба статические и volatile.

 class Helper implements Runnable{ 

      @Override 
      public void run() { 

       for(int i=0; i<100000;i++){   
        Runner.count+=1; 
       } 

      } 
     } 


     public class Runner { 

      public static volatile long count=0; // to be incremented 

      public static void main(String[] args){ 

       Thread t1 = new Thread(new Helper()); 
       Thread t2 = new Thread(new Helper()); 

       t1.start(); 
       t2.start(); 

       try { 
        t1.join(); 
        t2.join(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

       System.out.println("Count= "+count); // output expected to be 200000 
      } 

     } 

Ожидаемый результат для каждого запуска является Count = 200000, но иногда я получаю разное количество. Пожалуйста, помогите мне понять, как это возможно

+0

Летучий обеспечивает видимость, но не атомарность (это то, что требует составная операция, такая как приращение переменной). – Kayaman

ответ

3

Эффект летучего ключевого слова приблизительно, что каждая отдельная операция чтения или записи на этой переменной является атомарной.

Примечательно, однако, что операция, требующая более одного чтения/записи, такая как i ++, которая эквивалентна i = i + 1, которая делает одно чтение и одну запись, не является атомарной, поскольку другой поток может писать i между чтением и записью.

2
Runner.count+=1; 

означает:

Runner.count = Runner.count + 1; 

или, другими словами:

  1. Получить значение Runner.count.
  2. Добавить 1 в это значение.
  3. Сохраните новое значение в Runner.count.

Thread А и В можно как получить значение Runner.count (так они оба получают: 1), а затем и добавить к нему 1 в то же время (так что они оба получают 2), а затем и сохранить его обратно в то же время (поэтому новое значение равно 2) - и теперь значение изменилось с 1 на 2, а не с 1 на 3, хотя два потока увеличили его!

Смежные вопросы