1. 程式人生 > >java執行緒同步中使用自增操作時的注意

java執行緒同步中使用自增操作時的注意

在這裡講一個很多新手可能會出錯的地方:就是線上程中進行加法操作,這裡說的是 在多執行緒中操作同一份記憶體中的資料,然後對其進行加法運算
不要覺得不就是加法嘛,會有什麼問題。要是這樣我還說個球啊!!不過,講道理我在大學裡學習資料庫的理論知識的時候也沒記得說加法也會存線上程同步的問題。廢話不多說先來看一個簡單的例子

class MyThread extends Thread{
  public void run(){
    ++x;
  }
}

其中的x是全域性靜態變數,然後啟動多個MyThread。不要被我忽悠了,上面的例子本身是沒有什麼問題的,但是如果你覺得完全可以這樣使用那你就等著找問題吧!!!不信的話可以試試下面這個例子

class MyThread extends Thread{
    int i=0;
  public void run(){
  while(i<400)
    ++x;
    i++;
  }
  if(x==1600){
  //列印資訊,提示x到了1600
  }
}

上面的x依舊是全域性靜態變數,初始值為0,i是區域性變數,然後啟動4個執行緒執行起來,單單用想的話最後會打印出x到1600的提示資訊,但是當你真的運行了之後發現,x基本上都不會到1600,然而你列印i的值看下卻可以看到四個執行緒的i都已經等於400,那麼我們的問題就來了,為什麼i到了400而x卻沒有到1600。===================================================================================================================================
不用想了,我也不知道原理,所以也沒辦法告訴你,如果有興趣的話可以去看下java的編譯原理、java虛擬機器什麼的應該能找到答案,你也不用再嘗試什麼x++或者x=x+1什麼的,我可以告訴你這跟這些沒關係。所以這裡我只是善意的提醒一下要注意自增在java中也是執行緒不安全的,如果非要用的話可以使用synchronized關鍵字或者AtomicInteger(一個提供原子操作的Integer的類),不知道怎麼用的自行查閱。
最後還要注意上面說的是繼承Thread的執行緒,還有實現Runnable介面的執行緒,而Runnable中要注意的一點是其中的資料都是執行緒共享的,所以像上面例子中的i,在實現Runnable介面的執行緒中也不能直接隨意使用。