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它,并从不同的线程调用它