【发布时间】:2020-07-31 07:12:52
【问题描述】:
在这种情况下何时调用doneSignal.await()??
我的要求是等待回电,直到收到回调。
我尝试在其他线程和主线程中调用它。但是运气不好,从未收到回调,从而冻结了应用程序,最初当我不使用 CountDownLatch 时,getCall 立即返回空值,而无需等待回调。下面是我的代码
public UserSubscriptions getDocument(final String uid) {
final UserSubscriptions[] userSubscriptions = new UserSubscriptions[1];
final CountDownLatch doneSignal = new CountDownLatch(1);
try {
Thread getCall = new Thread(new Runnable() {
@Override
public void run() {
try{
DocumentReference docRef = db.collection("xyz").document(uid);
docRef.get()
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
userSubscriptions[0] = null;
TimerLog.e("document retrieve failed");
doneSignal.countDown();
}
})
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
userSubscriptions[0] = documentSnapshot.toObject(UserSubscriptions.class);
TimerLog.e("document retrieved successfully " + userSubscriptions[0].toString());
doneSignal.countDown();
}
});
TimerLog.e("control exitted from run");
} finally {
TimerLog.e("Nads in finally");
}
}
});
getCall.start();
TimerLog.e("before");
doneSignal.await();
TimerLog.e("after");
} catch (InterruptedException e) {
TimerLog.e("exception in await "+e.getLocalizedMessage());
}
return userSubscriptions[0];
}
控制台输出:
before
control exitted from run
in finally
【问题讨论】:
-
您不需要同时加入和等待。我的猜测是线程终止而不触发成功或失败回调。也许有一个异常(你没有捕获运行时异常)?在 run 方法中添加一个 try/finally 块,并在它退出时记录。您还可以捕获 Exception 或 Throwable 以记录错误(如果有)以进行调试。
-
@ewramner 在使用闩锁之前我使用的是
join()。现在尝试将其删除,并在try块内写入运行方法的内容,但没有发生异常,仍然应用程序冻结。一旦控件到达await,它甚至不会收到导致冻结的回调。 -
但是控制是否从 run 方法中退出(即登录您的 finally 块)?我认为注册成功和失败监听器不会阻塞,所以 run 方法只是返回并且没有调用回调。然后应用程序将挂起。
-
@ewramner 是的,控制退出运行。已更新代码以及控制台日志。我唯一担心的是我没有收到回调。
标签: java android multithreading