2011-01-14 79 views
42

望着SharedPreferences docs它說:SharedPreferences和線程安全

「注:目前這一類確實在多個流程不 支持使用 這將在以後添加。」

因此,它本身看起來並不是線程安全的。然而,對commit()和apply()做出了什麼樣的保證呢?

例如:

synchronized(uniqueIdLock){ 
    uniqueId = sharedPreferences.getInt("UNIQUE_INCREMENTING_ID", 0); 
    uniqueId++; 
    sharedPreferences.edit().putInt("UNIQUE_INCREMENTING_ID", uniqueId).commit(); 
} 

會是保證了UNIQUEID總是在這種情況下獨特之處?

如果沒有,是否有更好的方法來跟蹤持續存在的應用程序的唯一ID?

+3

示例代碼與非最終字段同步並對其進行更改。我懷疑你想這樣做。 – Bloodboiler 2013-02-07 15:07:46

+1

哎呀,很好。 – cottonBallPaws 2013-02-07 16:55:16

+1

什麼是uniqueIdLock?它在哪裏定義?它是靜態的,最終的公衆等?也許你應該轉換接受的答案? – 2013-09-18 15:27:24

回答

77

進程和線程都是不同的調用它。 Android中的SharedPreferences實現是線程安全的,但不是流程安全的。通常,您的應用程序將在同一個進程中運行,但您可以在AndroidManifest.xml中配置它,因此,服務在單獨的進程中運行,而不是在活動中運行。

要驗證安全性,請參閱AOSP中的ContextImpl.java的SharedPreferenceImpl。請注意,無論您希望哪裏有一個,都可以實現同步。

private static final class SharedPreferencesImpl implements SharedPreferences { 
... 
    public String getString(String key, String defValue) { 
     synchronized (this) { 
      String v = (String)mMap.get(key); 
      return v != null ? v : defValue; 
     } 
    } 
... 
    public final class EditorImpl implements Editor { 
     public Editor putString(String key, String value) { 
      synchronized (this) { 
       mModified.put(key, value); 
       return this; 
      } 
     } 
    ... 
    } 
} 

但是你唯一ID的情況下,它似乎你還是希望有一個同步的,你不希望它get和看跌之間切換。

3

我認爲這樣做。

您可以使用同步段內睡眠測試,並從不同的線程

4

你應該知道SharedPreferences在三星手機上沒有工作,看看android issue

我已經實現了簡單的數據庫首選項存儲,您可以在github上找到它。

乾杯,

4

我想知道同樣的事情 - 和整個this thread,說他們不是線程安全的傳來:

Context.getSharedPreferences()和Editor.commit 的實現()不要在同一臺顯示器上同步。


我後來看了一下Android的代碼14來檢查,這是相當複雜。具體SharedPreferencesImpl似乎用不同的鎖閱讀&寫入磁盤時:在thismWritingToDiskLock

  • startLoadFromDisk()

    • enqueueDiskWrite()鎖,並啓動對SharedPreferencesImpl.this

    我一個線程鎖定米不相信這個代碼真的是安全的。