2012-10-05 54 views
1

我是新來的Android編程和「之前已經研究不透的Java。我如何使用​​以確保static variables線程安全真的很困惑:Java中,正確使用靜態變量,以避免死鎖 - 同步

我通常會創建一個名爲Utils類有一些static functions其中最具借我的所有其他類所需要的時間。這是從我的課程中保留重複代碼的正確方法。

我總是遇到與使用數據庫的問題。當我創建了某些數據庫sqliteHelper類,並嘗試從說,一個活動和後臺服務來管理數據庫,我通常會 陷入困境。如果我用的輔助類的局部對象,我要進入數據庫的死鎖最大時容易出現兩個輔助對象試圖獲取寫鎖在一起。

爲了走出這一困境的,我在utils類創建輔助類的static實例。現在對數據庫進行任何操作我的行爲和我的服務做以下的事情:

public class Utils{ 
      public static MDatabaseHelper mHelper; 
      public static void instantiateHelper(Context context){ 
      if(mHelper==null) 
       mHelper=new MDatabaseHelper(context); 

      } 
    } 



    public class mActivity extends Activity{ 
    public void insert some item in database(final Item item) // this method is called in the Activity at some time 
    (new Thread(){ 
     @Override public void run(){ 
     Utils.instantiateHelper(getBaseContext()); 
     mHelper.insertItem(item); } 
     }).start(); 
    } 




public class mService extends Service{ 
     public void insert some item in database(final Item item) // this method is called in the service at some time 
      (new Thread(){ 
      @Override public void run{ 
      Utils.instantiateHelper(getBaseContext()); 
      mHelper.insertItem(item); } 
     }).start(); 
    } 

現在,如果雙方在服務和活動嘗試一起插入項目。我經常會遇到這種情況,併發生錯誤。 爲了避免這種情況我使用此解決方法:

我把插入操作在try塊,失敗我等待隨機的時間,然後再試一次

public void insertSomeItemInDatabase(final Item item) 
    (new Thread(){ 
      @Override public void run(){ 
       int i=0; 
       Random rand=new Random(); 
       while(true){ 
        if(i>10) 
        return; 
        try{ 
        Utils.instantiateHelper(getBaseContext()); 
        mHelper.insertItem(item); 
        break; 
        }catch(Exception e){ 
         i++; 
          try{ 
           Thread.sleep(rand.nextInt(1000)); 
           }catch(Exception e){} 
         } 

         } 
      } 
      } 
     }).start(); 
    } 

我知道這是對最差方法同步但由於我太新鮮了java任何一個可以請解釋如何在這種情況下使用​​。

謝謝

+0

爲什麼你的insertSomeItemInDatabase沒有同步? – njzk2

+0

供參考:您的方法是網絡協議中的常用方法。它有點類似於[Aloha協議](http://en.wikipedia.org/wiki/ALOHA_protocol#The_ALOHA_protocol)。如果你想堅持這種方法,你可能想申請[exponantial back off](http://en.wikipedia.org/wiki/Exponential_backoff)。 – amit

+0

我不太瞭解同步靜態變量。一個代碼片段和解釋將是一個很好的幫助@ njzk2 –

回答

1

我認爲所有您需要的是創造應用類

[1]這是在所有其他類中使用你已經採取的Util所有這些變量,可以被帶入這個應用程序類。所以這些變量將可用於所有其他類。

[2]創建Singelton實例申請類別。只是谷歌關於它。

[3]同時創建DataBaseHelper的Singleton(如果可能並且可以應用),所以,單實例可以幫助你在每個地方。


應用程序類是Android中的全局類,因此您可以使用它來存儲和訪問所有Global-Data。例如:

public class AppData extends Application { 

    public static AppData appData; 

    public int currentUserId; // etc. 

    //Const. 
    public AppData() { 
     appData = this; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     loginPreferences = getSharedPreferences(
      SPF_NAME, 0); 

     pathToSDCard = Environment.getExternalStorageDirectory().getAbsolutePath(); 
     System.out.println("Path : " + pathToSDCard); 
     //etc. 
    } 

// MOST IMP FOR GETTIN SINGELTON INSTANCE  <<<---<<<---<<<--- 
    public static AppData getAppData() { 
     return appData; 
    } 
} 

如何使用它,請參閱本

class ABC extends Activity { 
    AppData appData; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.xyz); 

     appData = AppData.getAppData(); 
     ........... 
     ........... 

     appData.VARIABLE_NAME... 
    } 
} 

還有一件事。在AndroidMenifest中。xml

... 
    ... 
<application    // In Application Tag 
     android:name="PACKAGE_NAME.AppData" // << Add here class name in which you have extended Application 
     android:icon="@drawable/ic_launcher" 
    ... 
    ...