多线程访问同步语句



我正在尝试在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.

现在,数据库有不打算发送的数据

为了解决这个问题,我实现了一个同步语句。首先这是我的锁:

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...");
}

从ui读取类似的内容:

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的android:process属性,现在同步块按预期工作。

虽然我想知道是否有一种方法来同步跨进程,因为它会更好的应用程序的分配内存。也许将锁传递给bundle中的适配器,但我不确定它是否会起作用,或者AIDL, Messenger。我不确定。

我认为你可以使用MemoryFile来同步进程。

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

  2. process1只读sharedmemory1,只写sharedmemory2。

  3. 任何进程都应该先写它可以写的共享内存,然后在进程想要写同步字段之前检查它可以读的共享内存

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

最新更新