看着 共享流程文档 它说:

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

因此,它本身似乎并不是线程安全。但是,在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

我不相信此代码确实是安全的。

您应该注意,共享流程不在用于三星手机,请看一下 Android问题.

我已经实现了简单的数据库首选项存储,您可以在 github.

干杯,

我认为那会做到。

您可以使用同步部分内的睡眠来对其进行测试,并从不同的线程调用它

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top