我试图在Android中实现线程安全操作。我使用SyncAdapter
将数据发送到服务器。问题是用户可以修改发送的相同数据,在发送数据后,我将当前存储的数据(可能已修改)与刚刚发送的数据进行比较。
我想避免这种情况:
(SyncAdapter thread) - data sent to server
(SyncAdapter thread) - comparing data
(SyncAdapter thread) - result: the data was not modified
(UI thread) - main thread updates the database
(SyncAdapter thread) - set the data to a sent state.
现在,数据库中包含不会发送的数据
为了解决这个问题,我实现了一个synchronized语句。首先,这是我的锁:
public class Lock {
public final static Lock lock = new Lock();
private Lock() {}
}
这是来自SyncAdapter.onPerformSync()
的代码,因为你可以看到睡眠线程能够测试它:
synchronized (Lock.lock) {
Log.d(TAG, "inside synchronized block...");
if (isDataUnchanged()) {
Log.d(TAG, "data compared...");
Thread.sleep(5000);
// update data state to 'sent'
provider.update(mUri, cValues, null, null);
}
Log.d(TAG, "exits synchronized block...");
}
来自UIThread的类似的东西:
synchronized (Lock.lock) {
Log.d("UIThread", "inside synchronized");
...
getActivity().getApplicationContext().getContentResolver().update(uri, cv, null, null);
}
但是当我测试它时,我看到UIThread在它不应该进入同步语句时。或者至少那是我所期望的,因为两种陈述的锁定是相同的。
D/SyncAdapter﹕ inside synchronized block...
D/SyncAdapter﹕ Data is the same
D/SyncAdapter﹕ data compared...
D/UIThread﹕ inside synchronized
D/SyncAdapter﹕ exits synchronized block...
修改
好吧,想想我明白了,我只是意识到SyncAdapter是在一个独立的进程中运行而不是应用程序。这肯定是锁不一样的原因。
Lock@415e69f0
Lock@417c6e88
修改2
在不同进程中运行的应用程序和SyncAdapter是原因。我将SynAdapter执行移动到应用程序进程,更改了SyncAdapter Service
的{{3}}属性,现在同步块按预期工作。
Altought我想知道是否有一种方法可以跨进程同步,因为它会更好地为应用程序分配内存。也许将锁传递给捆绑中的适配器,但我不确定它是否可行,或者可能是AIDL,Messenger。我不确定。
答案 0 :(得分:0)
我认为您可以使用MemoryFile跨进程进行同步。
使用两个共享内存sharedmemory1,sharedmemory2。
process1只读sharedmemory1并只写sharedmemory2。 process2只读sharedmemory2并只写sharedmemory1。
任何进程都应该首先编写可以编写的sharedmemory,然后在进程想要写同步字段之前检查它可以读取的sharedmemory。
我不确定这个建议是否有效。只是一个想法,希望能帮助你。