Android锁定线程中的CountDownLatch

bar*_*e.m 1 java multithreading android countdownlatch android-volley

我刚开始玩CountDownLatch我的Android应用程序.目前我正在尝试向Volley我的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();
    }
Run Code Online (Sandbox Code Playgroud)

问题是它似乎没有"完成"倒计时,因此冻结因为锁存器永远不会被释放.我已经确认API请求正在运行并且onSuccess回调被成功命中,但线程挂起.

更新 我刚注意到,CountDownLatch设置为0时,它会命中onSuccess,但当我将其设置为大于0的任何值时,它会冻结并且onSuccess永远不会被调用.看起来像线程的时髦.

Nic*_*tto 6

您的代码太容易出错,您需要调用countDown()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();
    }
});
Run Code Online (Sandbox Code Playgroud)