2014-10-26 6 views
2

Я читал раздел об изменчивой переменной в JSL. Спектр дает пример, и я попытался поэкспериментировать с ним. Я написал код:Понимание изменчивой переменной на примере

static volatile int i = 0, j = 0; 

public static void main(String args[]) { 
    Thread t1 = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      for (int k = 0; i < 200000; k++) { 
       i++; 
       j++; 
      } 
     } 
    }); 
    Thread t2 = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      for (int k = 0; i < 200000; k++) { 
       System.out.println("i=" + i + " j=" + j); 
      } 
     } 
    }); 
    t1.start(); 
    t2.start(); 
} 

Ok, я ожидал, что j<=i (спецификация говорит, что), но это не так:

i=147609 j=147684 
i=149412 j=149521 
i=150447 j=150523 
i=151384 j=151457 
i=152307 j=152380 
i=153222 j=153297 
i=154139 j=154214 
i=155065 j=155138 
i=155967 j=156040 
i=156880 j=156952 
i=157790 j=157863 
i=158760 j=158833 
i=159671 j=159747 
i=160592 j=160664 
i=161510 j=161584 
i=162420 j=162497 
i=163350 j=163425 
i=164292 j=164365 
i=165230 j=165306 
i=166179 j=166252 
i=167113 j=167187 
i=168055 j=168128 
i=169002 j=169078 
i=169948 j=170021 
i=170898 j=170974 
i=171851 j=171924 
i=172794 j=172866 
i=173724 j=173796 
i=174658 j=174733 
i=175641 j=175714 
i=176572 j=176645 
i=177503 j=177575 
i=178442 j=178517 
i=179394 j=179467 
i=180328 j=180403 
i=181276 j=181351 
i=182232 j=182305 
i=183178 j=183251 
i=184130 j=184205 
i=185092 j=185167 
i=186043 j=186118 
i=186998 j=187071 
i=195792 j=195866 
i=196718 j=196784 
i=197629 j=197698 
i=198543 j=198608 
i=199489 j=199555 

Что случилось?

+2

Цитата со страницы, на которую вы ссылались: * Возможно, однако, что любое задание вызова метода два может наблюдать значение j, которое намного больше, чем значение, наблюдаемое для i, потому что метод один может выполняться много раз между моментом, когда метод два извлекает значение i и момент, когда метод два извлекает значение j. * Таким образом, нет, spec не сказал «это». –

ответ

3

Фактическая ценность i всегда будет больше или равна j.

То, что вы видите в журналах является не фактическая (текущая) стоимость i и j. Это значение i и j в момент их оценки.

Ваш связанный документ утверждает

Можно, однако, что любой вызов методы два может наблюдать значение J, что значительно больше, чем значение, наблюдаемое для я, потому что метод один может выполняться много раз между моментом , когда метод 2 выбирает значение i и момент, когда метод два извлекает значение j.

Thread t1 работает, увеличивает i и j кучу раз. Контекстный переключатель. Thread t2 работает, оценивает i и объединяет его. Контекстный переключатель. Тема t1 продолжает увеличиваться i и j. Контекстный переключатель. Thread t2 оценивает j и объединяет его. Таким образом, j по-прежнему меньше или равен i, вы просто оценили их в разное время.