SharedPreferences和线程安全

查看SharedPreferences文档,它说:

“注意:目前这个类不支持在多个进程中使用,这个将在稍后添加。”

所以它本身并不是线程安全的。 但是,对commit()和apply()做了什么样的保证呢?

例如:

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

在这种情况下,uniqueId总是唯一吗?

如果没有,是否有一个更好的方法来跟踪一个持续的应用程序的唯一ID?

进程和线程是不同的。 Android中的SharedPreferences实现是线程安全的,但不是过程安全的。 通常,您的应用程序将在同一个进程中运行,但是您可以在AndroidManifest.xml中configuration它,例如,服务在单独的进程中运行,而不是在活动中运行。

要validation安全性,请参阅AOSP中的ContextImpl.java的SharedPreferenceImpl。 请注意,在任何地方都可以find同步的地方。

 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和put之间改变。

你应该知道,SharedPreferences不能在三星手机上工作,看看android问题 。

我已经实现了简单的数据库首选项存储,你可以在github上find。

干杯,

我想知道同样的事情 – 并遇到这个线程 ,说他们不是线程安全的:

Context.getSharedPreferences()和Editor.commit()的实现不在同一监视器上同步。


我自从看了Android 14的代码来检查,这是相当复杂的。 具体来说, SharedPreferencesImpl在读取和写入磁盘时似乎使用不同的锁:

  • enqueueDiskWrite()locking在mWritingToDiskLock
  • startLoadFromDisk()locking在this ,并启动一个locking在SharedPreferencesImpl.this上的线程

我不相信这个代码真的是安全的。

我认为这样做。

你可以在synchronized节中使用sleep来testing它,并从不同的线程调用它

    Interesting Posts