-
11-10-2019 - |
题
看着 共享流程文档 它说:
“注意:目前,此类不支持跨多个进程的使用。这将在稍后添加。”
因此,它本身似乎并不是线程安全。但是,在commit()和applion()方面做出了什么样的保证?
例如:
synchronized(uniqueIdLock){
uniqueId = sharedPreferences.getInt("UNIQUE_INCREMENTING_ID", 0);
uniqueId++;
sharedPreferences.edit().putInt("UNIQUE_INCREMENTING_ID", uniqueId).commit();
}
在这种情况下,可以保证唯一的唯一ID始终是独一无二的吗?
如果没有,是否有更好的方法来跟踪持续存在的应用程序的唯一ID?
解决方案
过程和线程不同。 Android中的共享频率实现是线程安全,但不是过程安全。通常,您的应用程序将在同一过程中运行,但是您可以在AndroidManifest.xml中配置它,因此,例如,该服务在单独的过程中运行,而不是活动。
要验证螺纹安全性,请参见AOSP的ContextImpl.java的共享preferenceImpl。请注意,无论您期望有一个,都会有一个同步。
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之间进行更改。
其他提示
我想知道同样的事情 - 遇到了 这个线程 那就是他们不是线程安全的:
context.getSharedPreferences()和editor.commit()的实现不会在同一监视器上同步。
从那以后,我查看了要检查的Android 14代码,并且非常参与其中。具体来说 SharedPreferencesImpl
在阅读和写作磁盘时似乎使用不同的锁:
enqueueDiskWrite()
锁定mWritingToDiskLock
startLoadFromDisk()
锁定this
, ,并启动线程锁定SharedPreferencesImpl.this
我不相信此代码确实是安全的。
我认为那会做到。
您可以使用同步部分内的睡眠来对其进行测试,并从不同的线程调用它
不隶属于 StackOverflow