簡體   English   中英

聲明對象引用在Java中是易失的?

[英]Declaring object reference as volatile in Java?

我有一個看起來類似於以下內容的Spring bean類:

@Component
public class Foo{

    private Config conf;

    @PostConstruct
    public void init(){
        conf = ConfigFileLoader.loadConfigFromFile();
    }

    public Config getConfig(){
        return conf;
    }

    public void updateConfig(){
        conf = ConfigFileLoader.loadConfigFromFile();
    } 

}

ConfigFileLoader.loadConfigFromFile()從文件讀取配置,並返回一個新的Config對象。

有兩種類型的線程:

  • 更新程序線程:
    • 只有一個
    • 它定期調用updateConfig(當它檢測到配置文件上的更改時)
  • 讀者線程:
    • 多個線程正在使用Config對象調用getConfig來執行。
    • 只要最終讀取器線程開始獲取最新的Config對象,它就不會為當前執行而收到過時的Config對象實例。

我的問題是,我應該將私有conf字段標記為volatile還是為conf字段添加某種同步?

我擔心的是以下情形:Updater線程更新conf引用,但更改永遠不會對讀取器線程可見。

任何幫助或解釋將不勝感激。

無論您使用volatile還是采用@sibnick的建議並使用ReaderWriterLock,這里的危險是某些線程將長時間保留其自己的Config對象私有引用:

 Config myConfig = foo.getConfig();
 while (conditionThatWillBeTrueForManyIterations()) {
      doSomethingWith(myConfig);
 }

這是不可能的編寫代碼,將持續的時間,因為無論你用做一段時間自己的私人參考Config的對象,你會互斥之外做。

即使你只寫這個:

doSomethingWith(foo.getConfig());

其他一些線程可能會在foo.getConfig()調用與doSomethingWith(...)調用之間更新配置。

您的程序必須能夠應對這種可能性。

易失性=嘗試使其他線程看到對象狀態的更新值,不保證線程同步運行,並且不保證它們不會進入破壞他人線程工作的情況

通過內部鎖進行的同步代碼=嘗試確保線程看到更新的對象狀態+保證線程同步工作並互相等待,以防止相互干擾。

您在此處定義的裝入方法將具有非原子的指令集。它將讀取文件並更新要裝入的對象。

必須單次完成從單個線程進行的讀取和更新操作,而不會受到其他線程的干擾,並嘗試重做相同的操作。

不確定性不是解決問題的可靠方法,因為您的操作不是一個單一的聲明/分配過程。

建議使用:對象上的固有鎖,並使讀取和更新方法同步運行。

public class Foo{

    private Config conf;
    Object lock = new Object();
    @PostConstruct
    public void init(){
        synchronize(lock)
        {
            conf = ConfigFileLoader.loadConfigFromFile();
        }
    }

    public Config getConfig(){
        synchronize(lock)
        {
            return conf;
        }
    }

    public void updateConfig(){
        synchronize(lock)
        {
            conf = ConfigFileLoader.loadConfigFromFile();
        }
    }

}

暫無
暫無

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

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