2015-04-09 1 views
0

Run главноголетучего тест не соответствовал его случаться-перед функцией в JLS

public class ThreadTest { 
volatile int p = 0, q = 0; 
    public void test() throws InterruptedException { 
     Thread writeThread = new Thread(){ 
      public void run(){ 
       while (!isInterrupted()) { 
        p++; 
        q++; 
       } 
      } 
     }; 
     Thread readThread = new Thread(){ 
      public void run(){ 
       while (!isInterrupted()) { 
        //p should not be less than q 
        if(p<q){ 
         System.out.println("happen before violation p = " + p + ";q = " + q); 
        } 
       } 
      } 
     }; 
     writeThread.start(); 
     readThread.start(); 
     Thread.currentThread().sleep(2); 
     writeThread.interrupt(); 
     readThread.interrupt(); 
    } 

    public static void main(String[] args) throws InterruptedException { 
    new ThreadTest().test(); 
    } 
} 

выход

произойдет до нарушения р = 736; д = 827
произойдет до нарушения р = 4635; д = 4657
произойдет до нарушения р = 6421; д = 6440
произойдет до нарушения р = 8719; д = 8803

ответ

0

Вы должны прочитать р ПОСЛЕ д для того, чтобы их значения в «не меньше, чем» порядок:

int q_value = q; // Read 'q' once 
int p_value = p; // Read 'p' AFTER q 
if(p_value < q_value) // ... happens-before violation 

В этом случае летучий модификатор требуется только для д, и он может быть опущен для p без нарушения ограничений.

В вас исходный код ничто не мешает компилятору от чтения р ДО д. Таким образом, readThread может видеть значение p с 736-й итерацией writeThread, но см. q значение от 827-й итерации. Или readThread может видеть значение p с начала 100-й итерации (то есть p = 100), но см. Значение q с конца этой итерации (то есть q = 101).

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