簡體   English   中英

一個線程更新變量,另一個讀取它,我是否需要特殊的東西

[英]One thread updates variable and another read it, do I need something special

我有一個對象為“卡”的類。 此類不斷檢查對象是否不再為null。 只有另一個線程可以更新此對象。 我應該像下面的代碼那樣做嗎? 使用volatile嗎? 鎖(我不知道該怎么用)? 您推薦什么是最簡單的解決方案?

Class A{

 public Card myCard = null;


 public void keepCheck(){

    while(myCard == null){
       Thread.sleep(100)
    }
    //value updated
     callAnotherMethod();
 }

另一個線程具有以下內容:

public void run(){
     a.myCard = new Card(5);
 }

你有什么建議?

如果要輪詢從另一個線程進行修改,則該變量需要是可變的,但是更好的解決方案是使用wait() / notify()Semaphore來使其他線程保持睡眠狀態,直到初始化myCard變量為止。

看起來您有一個經典的生產者/消費者案例。

您可以使用wait()/ notify()方法處理這種情況。 請參見此處的示例: 如何在Java中使用等待和通知?

或在此處查看更多示例: http : //www.programcreek.com/2009/02/notify-and-wait-example/

您應該使用適當的等待事件(請參閱Guarded Block教程),否則冒着“監視”線程在看到Card完全初始化的成員字段之前看到引用的風險。 另外, wait()將允許線程進入睡眠狀態,而不是在緊的while循環中占用CPU資源。

例如:

Class A {

    private final Object cardMonitor = new Object();
    private volatile Card myCard;

    public void keepCheck () {
        synchronized (cardMonitor) {
            while (myCard == null) {
                try {
                    cardMonitor.wait();
                } catch (InterruptedException x) {
                    // either abort or ignore, your choice
                }
            }
        }
        callAnotherMethod();
    }

    public void run () {
        synchronized (cardMonitor) {
            myCard = new Card(5);
            cardMonitor.notifyAll();
        }
    }

}

在上面的示例中,我將myCard私有。 我確實建議在這種情況下避免使用大量公共字段,因為代碼最終可能很快變得混亂。

還要注意,您不需要 cardMonitor您可以使用A本身,但是擁有一個單獨的監視器對象可以使您更好地控制同步。

當心,通過上述實現,如果run()執行callAnotherMethod()調用callAnotherMethod() ,它將更改myCard ,這可能會破壞callAnotherMethod() (您未顯示)。 callAnotherMethod()移到同步塊內是一種可能的解決方案,但是您必須根據需要確定合適的策略。

暫無
暫無

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

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