簡體   English   中英

通過兩個不同的線程設置和訪問變量

[英]Setting and accessing a varibale by two different threads

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

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循環的條件始終為true System.out.println(getValue)始終顯示-1 我很奇怪,為什么第二個線程沒有得到新的價值value2 我不認為synchronized在這里很重要,因為一個線程正在設置變量,而另一個線程正在訪問變量。

這里有一些解決方案:

  1. 使用標准Java類AtomicInteger以多線程安全方式存儲您的值。 實際上,這是最好,最快的方法。
  2. synchronized關鍵字添加到您的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());
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM