2016-11-28 101 views
0

我有一個線程z,它是在單擊某個JButton begin時創建的。在該線程的運行方法中,我需要包含一個動態變量val,它會定期更改其值。全球已申報Val。 此更改通過JSlider的stateChanged函數正確建模,後者繼續在控制檯中輸出val的正確值。但是,在我的run方法中,變量val不會根據需要進行更改。它在線程創建時保持不變,作爲初始值。在Java中使用帶有線程的動態變量

這裏是我下面的功能:

int val; 
Thread z; 

public void actionPerformed(ActionEvent e) { 

    if (e.getSource().equals(step)) { 
     simulation(); 
    } 

    else if (e.getSource().equals(begin)) { 
     if (running==false) { 
      running = true; 
      z = new Thread(this); 
      z.start(); 
     } 
    } 

    else if (e.getSource().equals(end)) { 
     running = false; 
    } 
} 

@Override 
public void stateChanged(ChangeEvent e) { 
    val = slider.getValue(); 
    System.out.println(val); 
} 

@Override 
public void run() { 
    while (running==true) { 
     simulation(); 
     try { 
      Thread.sleep(val+200); //SHOULD BE DYNAMIC 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

} 

我如何可以改變變量val是動態的,任何想法,將不勝感激。

謝謝!

+0

你可以添加聲明'val'的完整類嗎? – developer

+0

它只是在構造函數方法中聲明。剛剛更新了...... – Eragon20

+1

聽起來像問題不是它不是「動態的」(在'stateChanged(ChangeEvent)'執行線程期間被更改)。我敢打賭你有這個類的兩個實例,一個運行在一個新的線程中,另一個運行於JSlider更新。你能分享你如何創建和啓動線程?另外,'val'變量並不是真正的「全局」。如果你把它定義爲「靜態」,那麼你可以認爲它是全局的,就像在課堂上一樣。 –

回答

1

的問題是你val不是volatile所以每當mainThread更新變量的runnable()Thread無法查看。

同樣確保您標記running變量(內部while循環使用)作爲volatile,否則runnable()線程將永遠運行(不脫離其他線程接收該更新)。

什麼是易失性?這是什麼意思?

簡而言之,將變量標記爲volatile使得一個線程的寫入對其他線程可見。這是必需的,因爲當一個線程寫入一個變量時,變量數據被緩存(對於線程是本地的),並且對於其他線程可能不可見,直到寫入線程刷新數據。因此,volatile確保數據不被緩存,而是始終從主內存寫入/讀取數據。

我建議您通過參考here來了解線程通信的基礎知識。

+0

什麼是'volatile'?這是什麼意思? – Eragon20

+0

https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html – developer

+0

啊哈!謝謝! – Eragon20