2016-09-23 82 views
0

我有兩個線程,一個設置類的變量,另一個通過get方法訪問變量。通過兩個不同的線程設置和訪問varibale

public class Parent { 
    private int value = -1 

    public int getValue() 
     return this.value; 
    } 

    public void setValue(int value){ 
     this.value = value; 
    } 

    private class UpdatingVaribale extends Thread { 

    public void run() { 
     while (!Thread.currentThread().isInterrupted()) { 
     try { 
      setValue(2); 
      Thread.currentThread().interrupt(); 
     } 
     } 
    } 
} 

private class GettingVaribale extends Thread { 

    public void run() { 
     while (getValue == -1) { 
     try{ 
      System.out.println(getValue); 
      Thread.sleep(500); 
     } catch (InterruptedException e) { 
     } 
     } 
     System.out.println(getValue); 
    } 
} 

的問題是,在第二線程中的while循環的條件總是trueSystem.out.println(getValue)總是打印-1。我想知道爲什麼第二個線程沒有得到value的新值,即2。我不認爲​​這裏很重要,因爲一個線程正在設置一個變量,另一個線程正在訪問變量。

+0

的可能的複製[你曾經使用Java中的volatile關鍵字?](http://stackoverflow.com/questions/106591/do-you-ever-使用volatile-keyword-in-java) – shmosel

+2

'synchronized'實際上可以解決你的問題,就像'volatile'或'AtomicInteger'一樣。線程安全不僅僅是競賽條件。 – shmosel

+0

@shmosel,因爲什麼時候它不會構成一個線程對不同線程寫入變量的非同步讀取的競爭條件?但是,是的,您列舉的幾種同步機制中的任何一種都可以解決問題。 –

回答

2

這裏有一些解決方案:

  1. 使用標準的Java類AtomicInteger在多線程安全的方式存儲你的價值。其實這是最好最快的方法。
  2. 添加​​關鍵字到getValuesetValue方法
  3. 添加volatile java的關鍵字i字段定義

你的問題的根源是i變量值實際上是在不同的線程導致CPU速度和內存看起來不同優化,你必須指定JVM以某種方式不要做這種優化,並且 - 相反 - 使最新的i值在所有線程中都可見。

更新測試代碼

public class SyncProblem { 

    public static void main(String[] args) { 
     Parent parent = new Parent(); 
     new Thread(parent.new GettingVaribale()).start(); 
     new Thread(parent.new UpdatingVaribale()).start(); 
    } 
} 

class Parent { 
    private volatile int value = -1; 

    public int getValue() { 
     return this.value; 
    } 

    public void setValue(int value) { 
     this.value = value; 
    } 

    class UpdatingVaribale implements Runnable { 
     @Override 
     public void run() { 
      while (!Thread.currentThread().isInterrupted()) { 
       setValue(2); 
       Thread.currentThread().interrupt(); 
      } 
     } 
    } 

    class GettingVaribale implements Runnable { 
     @Override 
     public void run() { 
      while (getValue() == -1) { 
       try { 
        System.out.println(getValue()); 
        Thread.sleep(500); 
       } catch (InterruptedException e) { 
       } 
      } 
      System.out.println(getValue()); 
     } 
    } 
} 
+0

我試過這三種解決方案。他們中沒有人解決了這個問題。 – Self

+0

@Sultan由於您的代碼有很多語法錯誤,我修復並將更新後的代碼放入我的答案更新中。您可以簡單地將其複製粘貼到IDE中並運行'main'方法。在程序退出之前,輸出就像'-1 2' –

相關問題