#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 секунд.