Java Android锁定线程中的倒计时锁存器

Java Android锁定线程中的倒计时锁存器,java,android,multithreading,android-volley,countdownlatch,Java,Android,Multithreading,Android Volley,Countdownlatch,我刚开始在我的Android应用程序中玩CountDownLatch。目前,我正在尝试向我的api发出两个截取请求,并等待数据被检索和存储后再继续执行线程 这是我的代码示例: // new CountDownLatch for 2 requests final CountDownLatch allDoneSignal = new CountDownLatch(2); transactions.getResourcesForRealm(Contact.class, "",

我刚开始在我的Android应用程序中玩
CountDownLatch
。目前,我正在尝试向我的api发出两个
截取
请求,并等待数据被检索和存储后再继续执行线程

这是我的代码示例:

    // new CountDownLatch for 2 requests
    final CountDownLatch allDoneSignal = new CountDownLatch(2);

    transactions.getResourcesForRealm(Contact.class, "", new ICallBack<Contact>() {
        @Override
        public void onSuccess(ArrayList<Contact> resources, String resourceId) {
            transactions.createRealmObject(resources, Contact.class);

            allDoneSignal.countDown();
        }

        @Override
        public void onFail(ArrayList<Contact> resources) {

        }
    });

    transactions.getResourcesForRealm(Meeting.class, "", new ICallBack<Meeting>() {
        @Override
        public void onSuccess(ArrayList<Meeting> resources, String resourceId) {
            transactions.createRealmObject(resources, Meeting.class);

            allDoneSignal.countDown();
        }

        @Override
        public void onFail(ArrayList<Meeting> resources) {

        }
    });

    try {
        allDoneSignal.await();
        // continue executing code
        // ...
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
//2个请求的新倒计时锁存器
最终倒计时锁存器allDoneSignal=新倒计时锁存器(2);
transactions.getResourcesForeralm(Contact.class,”,新的ICallBack(){
@凌驾
成功时的公共void(ArrayList资源、字符串资源ID){
createRealmObject(资源,Contact.class);
allDoneSignal.countDown();
}
@凌驾
public void onFail(ArrayList资源){
}
});
transactions.getResourcesForeralm(Meeting.class,”,新的ICallBack(){
@凌驾
成功时的公共void(ArrayList资源、字符串资源ID){
事务.createRealmObject(资源,会议.class);
allDoneSignal.countDown();
}
@凌驾
public void onFail(ArrayList资源){
}
});
试一试{
allDoneSignal.wait();
//继续执行代码
// ...
}捕捉(中断异常e){
e、 printStackTrace();
}
问题在于它似乎没有“完成”倒计时,因此会冻结,因为闩锁从未释放过。我已经确认API请求正在工作,并且成功命中了
onSuccess
回调,但线程挂起

更新
我刚刚注意到,
CountDownLatch
设置为0时,它会在成功时点击
onSuccess
,但当我将其设置为大于0的任何值时,它会冻结,并且永远不会调用
onSuccess
。线程似乎有些奇怪。

您的代码太容易出错,您需要在finally块中调用
倒计时()
,并在
onFail
中调用它,否则一旦失败,您的应用程序将永远冻结。因此,您的代码应该是:

transactions.getResourcesForRealm(Contact.class, "", new ICallBack<Contact>() {
    @Override
    public void onSuccess(ArrayList<Contact> resources, String resourceId) {
        try {
            transactions.createRealmObject(resources, Contact.class);
        } finally {
            allDoneSignal.countDown();
        }
    }

    @Override
    public void onFail(ArrayList<Contact> resources) {
        allDoneSignal.countDown();
    }
});

transactions.getResourcesForRealm(Meeting.class, "", new ICallBack<Meeting>() {
    @Override
    public void onSuccess(ArrayList<Meeting> resources, String resourceId) {
        try {
            transactions.createRealmObject(resources, Meeting.class);
        } finally {
            allDoneSignal.countDown();
        }
    }

    @Override
    public void onFail(ArrayList<Meeting> resources) {
        allDoneSignal.countDown();
    }
});
transactions.getResourcesForeralm(Contact.class,”,新的ICallBack(){
@凌驾
成功时的公共void(ArrayList资源、字符串资源ID){
试一试{
createRealmObject(资源,Contact.class);
}最后{
allDoneSignal.countDown();
}
}
@凌驾
public void onFail(ArrayList资源){
allDoneSignal.countDown();
}
});
transactions.getResourcesForeralm(Meeting.class,”,新的ICallBack(){
@凌驾
成功时的公共void(ArrayList资源、字符串资源ID){
试一试{
事务.createRealmObject(资源,会议.class);
}最后{
allDoneSignal.countDown();
}
}
@凌驾
public void onFail(ArrayList资源){
allDoneSignal.countDown();
}
});

很抱歉回答得太晚,但如果对任何人都有帮助:

您需要在单独的线程中执行“.await”,因为它会阻止当前线程

例如:

final Handler mainThreadHandler = new Handler(Looper.getMainLooper());
new Thread(new Runnable() {
    @Override
    public void run() {
        allDoneSignal.await();
        mainThreadHandler.post(new Runnable() {
            doSomethingWhenAllDone();
        });
}
}).start()

我可能是错的,但对于线程和值相关的问题,请检查Volatile variable
概念。这应该可以按预期工作-您可以在调用countDown之前记录一些内容,以确保方法确实被调用吗?@PradeepKumarKushwaha此处不需要Volatile,锁存器已经提供了足够的同步保证。我将尝试
Log.wtf
这个…你也可以说“2个请求的新倒计时锁存器”-可能会再次检查
allDoneSignal
变量在三个位置是否相同(如果代码与你在单个方法中发布的代码完全相同,那么它显然是相同的)…虽然这通常是一个很好的建议,但它并不能回答问题,这个问题非常糟糕,需要假设您不必这么做。@SleimanJneidi是的,我知道,但我们都知道倒计时闩锁工作得很好,所以如果程序冻结,这是因为倒计时()由于某些原因,调用的次数没有预期的两倍,因此我只提供了一种方法,确保即使在失败的情况下也会调用它,以便更好地处理错误,我已经实现了这一点,并且我正在试图弄清楚为什么它没有命中
倒计时()
@barnacle.m我相信这意味着onSuccess是由调用线程调用的,尝试打印Thread.currentThread()的值。我已尝试将闩锁作为异步请求的参数传入,并在新线程中倒计时。它仍然挂着。