我有一个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对传入的请求进行排队。我对吗?我应该考虑和教育自己的哪些经营者?
或者我是以完全错误的方式接近这个? 从我的大部分谷歌搜索中我发现,问题主要在于我在循环中像我一样启动方法。我没有使用任何。在我的情况下,问题是这个方法是由多个响应启动的,并且由于当前的后端实现而改变这种方法是不可能的。
答案 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();
}
}