对同步语句的多线程访问

时间:2015-10-13 22:01:06

标签: java android

我试图在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。我不确定。

1 个答案:

答案 0 :(得分:0)

我认为您可以使用MemoryFile跨进程进行同步。

  1. 使用两个共享内存sharedmemory1,sharedmemory2。

  2. process1只读sharedmemory1并只写sharedmemory2。 process2只读sharedmemory2并只写sharedmemory1。

  3. 任何进程都应该首先编写可以编写的sharedmemory,然后在进程想要写同步字段之前检查它可以读取的sharedmemory。

  4. 我不确定这个建议是否有效。只是一个想法,希望能帮助你。