1

Я только начал играть с CountDownLatch в своем приложении для Android. В настоящее время я пытаюсь сделать два запроса Volley на мой api и дождаться, пока данные будут извлечены и сохранены, прежде чем продолжить выполнение потока.CountDownLatch в Android lock thread

Это пример моего кода:

// 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(); 
    } 

Вопрос заключается в том, что он, кажется, не «полный» обратный отсчет времени, и поэтому замерзает, потому что защелка никогда не освобождается. Я подтвердил, что запросы API работают, и обратный вызов onSuccess успешно удался, но зависает нить.

UPDATE Я только заметил, что с CountDownLatch установлен в 0, она попадает onSuccess, но когда я поставил его на что-либо большее, чем 0, она замерзает и onSuccess никогда не вызывается. Кажется, что-то напуганное с резьбой.

+0

Возможно, я ошибаюсь, но для вопросов, связанных с потоком и стоимостью, пожалуйста, проверьте концепцию «Неустойчивая переменная». –

+0

Это должно работать так, как ожидалось - можете ли вы записать что-то непосредственно перед вызовом countDown, чтобы убедиться, что метод действительно вызван? – assylias

+1

@PradeepKumarKushwaha Здесь нет необходимости в изменчивости, защелка уже дает достаточные гарантии синхронизации. – assylias

ответ

5

Ваш код слишком подвержен ошибкам, вам нужно позвонить 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(); 
    } 
}); 
+0

Хотя это хороший совет в целом, он не отвечает на вопрос, вопрос очень плохой и требует предположения, что вам не нужно делать. –

+0

@SleimanJneidi Да, я знаю, но мы все знаем, что CountDownLatch работает хорошо, поэтому, если программа зависает, это потому, что countDown() по какой-то причине не вызывается дважды, как ожидается, поэтому я просто предоставляю способ убедиться, что он вызывается даже в случае от неудачи –

+0

Спасибо за хорошую обработку ошибок, я реализовал это, и я пытаюсь понять, почему он не ударил 'countDown()' –