2016-08-04 112 views
-1

嗨我想了解下面的代碼的輸出。根據我的理解,輸出可能會不同的第一和第二個線程。但是當我執行下面的代碼很多次,我仍然得到兩個線程的值相同。無論我是錯的還是正確的,都可以請一些人點亮。多線程程序的輸出

package com.vikash.Threading; 

public class ThreadLocalExample { 

    public static class MyRunnable implements Runnable { 

     @SuppressWarnings("unused") 
     private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); 
     D d=new D(); 

     @Override 
     public void run() { 
      //threadLocal.set((int) (Math.random() * 100D)); 
      d.setX((int) (Math.random() * 100D)); 
      //System.out.println(Thread.currentThread().getName()+" "+threadLocal.get()); 
      System.out.println(Thread.currentThread().getName()+" "+d.getX()); 
      try { 
       Thread.sleep(200); 
      } catch (InterruptedException e) { 
      } 
      //System.out.println(Thread.currentThread().getName()+" "+threadLocal.get()); 
      //System.out.println(Thread.currentThread().getName()+" "+d.getX()); 
     } 
    } 

    public static void main(String[] args) throws InterruptedException { 

     MyRunnable sharedRunnableInstance = new MyRunnable(); 

     Thread thread1 = new Thread(sharedRunnableInstance); 
     Thread thread2 = new Thread(sharedRunnableInstance); 

     thread1.start();thread1.setName("First"); 
     thread2.start();thread2.setName("Second");; 

     thread1.join(); //wait for thread 1 to terminate 
     thread2.join(); //wait for thread 2 to terminate 
    } 
} 
+0

@Vikash:代碼缺乏同步的,這意味着,正式,結果未完全指定。換句話說,你不能保證結果會是什麼。但是,您也沒有任何保證,如果您多次運行它,*會看到不同的結果。可能發生的情況是,在特定的系統中,在特定的JVM版本,Java編譯器等中,它可能會發生,您將始終看到相同的結果。但是,正式的說法(即根據JVM規範),你的代碼不能保證有任何特定的結果。 –

+0

@Vikash:你可以通過多次運行「證明」自己的唯一一件事是:如果你看到不同的結果,你就有*缺乏同步的證據。但是,如果您運行多次並始終看到相同的結果,則您沒有任何證據。測試同步問題真的很難! –

回答

1

這是因爲你沒有在d同步,所以會發生什麼是線程1臺X值,那麼線程2套x值,則跟帖說已經由線程2同步塊使復位1個打印值確保正確的值被印刷

synchronized (d) { 
    d.setX((int) (Math.random() * 100D)); 
    System.out.println(Thread.currentThread().getName() + " " + d.getX()); 
} 
+1

(該死的,在嘗試添加更多文本時意外丟失了我的評論;重寫它)在兩個線程都啓動之前,字段'd'被初始化,所以這裏有一個發生前的關係。初始化後,沒有什麼會改變字段'd'。這意味着這兩個線程都保證讀取正確初始化的字段'd'。添加'volatile'不會改變任何東西:唯一可變的是建立發生 - 在寫入到易失性字段的關係之後,讀取相同的易失性字段。 –

+0

@BrunoReis你是對的,揮發性是不夠的。相應地編輯我的答案。感謝您指出了這一點 – noscreenname