Потоковая обработка Android — повторить группу потоков несколько раз с задержкой

#java #android #multithreading #queue

#java #Android #многопоточность #очередь

Вопрос:

Я собираюсь реализовать приложение, которое собирает данные с устройства Android.

Вот что у меня есть прямо сейчас:

  • Основное действие с помощью кнопки Выполнить
  • Кнопка запускает запись
  • У Recorder есть 4 ресурса, которые могут быть запущены
    • GpsResource
    • ImageResource
    • Аудиоресурс
    • GyroscopeResource
  • В Recorder есть цикл for (например i < 3 ), который запускает пакет потоков с некоторой задержкой ( i * 5000 )

Как я должен создать эти потоки, чтобы все они запускались одновременно ( i=0 ), затем через 5 секунд запускались снова ( i=1 ) и через следующие 5 секунд снова ( i=2 )?

Следующее:

Каждый ресурс возвращает некоторые данные с помощью getData() метода — упростить его — строки со случайными символами. Как уведомить в Recorder, что все потоки в очереди завершены и собирают все данные из ресурсов?

Последнее, что:

Я должен иметь возможность после создания всех этих очередей прекратить выполнение всех потоков. Пример:

У нас есть 7-я секунда, сейчас запущена 2-я очередь, и пользователь нажимает кнопку Стоп. Очередь с запущенными потоками завершается, но следующие очереди не запускаются, просто перекодированный должен забыть о них.

Я пытался написать как можно проще, я верю, что вы, ребята, меня понимаете.

Спасибо за любые советы!

Ответ №1:

Вот идея решить хотя бы одну часть вопроса:

Для совместного запуска ресурсов и ожидания их завершения:

Возьмите CompletionService :

 Executor e = Executors.newFixedThreadPool(4);
CompletionService<String> service = new ExecutorCompletionService<String>(e);
CountDownLatch startLatch = new CountDownLatch(1);
for (int i=0; i<numberOfResources; i  ) {
     Resource r = createResource(startLatch, i);
     service.submit(r);
}
startLatch.countDown();
  

Resource должно выглядеть примерно так:

 class Resource implements Callable<String> { 
    private final CountDownLatch latch;
    public Resource(CountDownLatch latch) { this.latch = latch; }
    public String call() throws Exception {
        latch.await();
        return getData();
    }
}
  

Не получить данные обратно из службы завершения:

 for (int i=0; i<numberOfResources; i  ) {
    String data = service.take().get();
    // do something with data
}
  

Пожалуйста, обратите внимание, что это скорее псевдокод, фактически не протестированный 🙂

И все еще остаются открытыми вопросы, что бы вы сделали, если выполнение какого-либо ресурса занимает более 5 секунд. Другой способ заключается в планировании одних и тех же операций каждые 5 секунд.