领域 - 实现异步队列

时间:2017-04-18 16:17:07

标签: java android asynchronous realm rx-java

我有一个dagger-singleton-wrapper处理我的基本Realm请求。其中一个看起来像这样:

public void insertOrUpdateAsync(final List<RealmMessage> messages, @Nullable final OnInsertListener listener) {
    Realm instance = getRealmInstance();
    instance.executeTransactionAsync(realm -> {
                List<RealmMessage> newMessages = insertOrUpdateMessages(realm, messages);
            },
            () -> success(listener, instance),
            error -> error(listener, error, instance));
}

private List<RealmMessage> insertOrUpdateMessages(@NonNull Realm realm, @NonNull final List<RealmMessage> messages) {
    ...
    return realm.copyToRealmOrUpdate(unattendedMessages);
}

哪个效果很好。

然而,有一个角落的情况 - 长话短说 - 我多次启动insertOrUpdateAsynch()。经过一些要求后,我得到了这个:

Caused by: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@b7b848 rejected from io.realm.internal.async.RealmThreadPoolExecutor@80f96e1[Running, pool size = 17, active threads = 17, queued tasks = 100, completed tasks = 81]

我的问题是:如何在不重建整个应用程序流程的情况下处理这个问题。 我的想法是通过RxJava对传入的请求进行排队。我对吗?我应该考虑和教育自己的哪些经营者?

或者我是以完全错误的方式接近这个? 从我的大部分谷歌搜索中我发现,问题主要在于我在循环中像我一样启动方法。我没有使用任何。在我的情况下,问题是这个方法是由多个响应启动的,并且由于当前的后端实现而改变这种方法是不可能的。

1 个答案:

答案 0 :(得分:0)

如果您不想重新设计应用程序,可以使用计数信号量。您将看到两个线程将立即获得锁定。另一个线程将阻塞,直到某个调用将释放一个锁。不建议在没有超时的情况下使用acquire()。

为了使用RxJava,您必须更改应用程序的设计,并且RxJava中的速率限制并不那么容易,因为它完全取决于整个输出。

private final Semaphore semaphore = new Semaphore(2);

@Test
public void name() throws Exception {
    Thread t1 = new Thread(() -> {
        doNetworkStuff();
    });
    Thread t2 = new Thread(() -> {
        doNetworkStuff();
    });
    Thread t3 = new Thread(() -> {
        doNetworkStuff();
    });

    t1.start();
    t2.start();
    t3.start();

    Thread.sleep(1500);
}

private void doNetworkStuff() {
    try {
        System.out.println("enter doNetworkStuff");

        semaphore.acquire();

        System.out.println("acquired");

        Thread.sleep(1000);

    } catch (InterruptedException e) {
        e.printStackTrace(); // Don't do this!!
    } finally {
        semaphore.release();
    }
}