2017-05-29 33 views
0

我創建了兩個線程在主要活動中操縱共享領域的成員,但價值似乎不是線程更新,因爲變量的值是一樣的,實際上是即時通訊練同步,這裏是我的代碼:安卓:線程不更新值

public class ActMain extends Activity { 

Handler handler; 
Integer THREAD_COUNTER = 10; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_act_main); 

    Message m = new Message(); 
    Bundle b = new Bundle(); 
    b.putInt("what", 5); 
    m.setData(b); 


    Thread t1 = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      for(int i =0; i < 10; i++){ 
       add(); 
      } 

     } 
    }); 

    Thread t2 = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      for(int i = 0; i < 30; i++){ 
       subtract(); 
      } 

     } 
    }); 

    t1.start(); 
    t2.start(); 

    Log.i("MainActivity " , " thread counter" + THREAD_COUNTER); 
    //same value 10 of THREAD_COUNTER 

回答

1

我在主要活動中創建了兩個線程來操作共享字段成員,但值似乎沒有被線程更新......

有幾個與你的代碼的問題。首先,您啓動2個線程,然後立即記錄結果。在執行Log.i(...)行時,線程可能實際上並未開始運行。等待後臺線程完成,你需要使用join()

t1.start(); 
t2.start(); 
// t1 and t2 start running in the background but we need to wait for them to finish 
t1.join(); 
t2.join(); 
Log.i(...); 

另一個問題是,你不能只是從2個線程加減在THREAD_COUNTER整數。線程從本地緩存內存中獲取性能,以便隨時線程共享信息,您需要擔心鎖定和內存同步,以便他們可以協調更新。

隨着在多線程環境整數,爪哇給我們的AtomicInteger class這是線程同時更新一個整數值的好方法。所以,你的代碼應該是這樣的:

// initialize our shared counter to 10 
final AtomicInteger threadCounter = new AtomicInteger(10); 
// ... 
// to add: 
threadCounter.addAndGet(5); 
// to subtract: 
threadCounter.addAndGet(-7); 
// ... 
// to get the value after the joins 
threadCounter.get(); 

情侶其他意見:

  • 全部大寫的字段是常數。 threadCounter而不是THREAD_COUNTER
  • 始終使用int,而不是Integer除非值可以是null
  • 不知道如果你這樣做,但never call synchronized on a value that can change like an Integer or Boolean。你必須在一個常量對象實例上進行同步,添加一些東西到Integer更改對象,以便多個線程將鎖定在不同的對象上。在private final字段上始終呼叫​​是一種很好的模式。
+0

這意味着我們可以指示其他線程等待,直到第一個線程完成加入,然後開始執行,同時我們還強制日誌只顯示第二個線程完成時,我們做t2.join();我們是否暫停主線程? – blackHawk

+0

也首先我做了t1.join,然後log1然後t2.join然後log2,有時我得到正確的執行t1-> log1-> t2-> log2有時t1-> t2-> log1-> log2,爲什麼它發生,有時也有t2-> t1-> log1-> log2 – blackHawk

+0

因爲線程是同步的。即使您先運行t1.join(),t2也可以完成_before_ t1。您希望通過線程操作獲得的控制越多,就越像是線程化程序。您不必擔心哪個線程先運行或先完成。 @黑鷹 – Gray

0

基本上當你做那些三線

t1.start(); 
t2.start(); 
Log.i("MainActivity " , " thread counter" + THREAD_COUNTER); 

它們都發生在同一時間,所以當Log.i發生你的線程計數器不更新,你可以使用的AsyncTask,並在打印結束的線程,或做 個log.i在線程本身,

當您打印這樣你只需打印線程更新變種之前。

更多關於多線程在Java(學習):

http://beginnersbook.com/2013/03/multithreading-in-java/

爲更多的AsyncTask(Android的線程有生命週期,所以你可以做的事情在UI一旦它已經結束了):

https://developer.android.com/reference/android/os/AsyncTask.html