編輯:關於android開發
一個線程中變量的修改可能不會立即對其他線程可見,事實上也許永遠不可見。
在代碼一中,如果一個線程調用了MyClass.loop(),將來的某個時間點,另一個線程調用了MyClass.setValue(100),第一個線程可能仍然不會終止,可能永遠循環下去
代碼一: public class MyClass{ private static final String TAG="MyClass"; private static int mValue=0; public static void setValue(int n){ mValue=n; } public static void loop(){ int value; while(value!=100){ try{ Log.i(TAG,"Value is "+value); Thread.sleep(1000); }catch(Exception e){ } } } }
上面的問題有兩種解決辦法:
一是使用synchronized關鍵字
public class MyClass{ private static final String TAG="MyClass"; private static int mValue=0; public static synchronized void setValue(int n){ mValue=n; } public static synchronized int getValue(){ return mValue; } public static void loop(){ int value; while((value=getValue())!=100){ try{ Log.i(TAG,"Value is "+value); Thread.sleep(1000); }catch(Exception e){ } } } }
二是使用volatile關鍵字
public class MyClass{ private static final String TAG="MyClass"; private static volatile int mValue=0;//添加volatile關鍵字 public static void setValue(int n){ mValue=n;//如果是mValue+=n,因為不是原子操作,還得使用synchronized } public static void loop(){ int value; while(value!=100){ try{ Log.i(TAG,"Value is "+value); Thread.sleep(1000); }catch(Exception e){ } } } }
value++不是原子的,value=1是原子的。volatile關鍵字只可以解決變量聲明是原子的那些並發問題,如果變量不是原子的就必須使用synchronized關鍵字
不要在synchronized塊中調用另一個對象的方法(它可能已經被鎖住並等待之前用到的對象解鎖),除非你能保證不會發生死鎖,通常情況下只有親手寫其他對象的類的代碼才敢確定不會發生死鎖。
Android ExpandableListView的技巧和問題,expandablelistview前言: 最近一個多月在認真的學習Android和做項目,文章內容表達
Android Animation學習 實現 IOS 濾鏡退出動畫,androidiosIOS的用戶體驗做的很好,其中一點很重要的地方就是動畫效果。 最近在學習Andro
Android 手機衛士--綁定sim卡序列號,androidsim現在開始具體 處理每一個導航頁面的邏輯,首先看第二個導航頁 本文地址:http://www.cnbl
android加固系列—6.仿愛加密等第三方加固平台之動態加載dex防止apk被反編譯,dexapk【版權所有,轉載請注明出處。出處:http://www.cnblogs