Как остановить поток main, пока все ArrayBlockingQueue не выполнятся?

236
09 февраля 2018, 20:42

Как остановить поток main, пока все ArrayBlockingQueue не выполнятся?
То есть, существует main поток в котором я запускаю другие потоки для выполнения в которых используется ArrayBlockingQueue. Когда я использую join то main останавливается, но потоки с ArrayBlockingQueue судя по всему должны останавливаться, но main не продолжает потом работу вообще. Если пользуюсь ThreadPoolExecutor и future то тоже самое. Но если main не остановить то он продолжает работу и конечно завершается на много раньше.

В дебаге вижу что потоки "потребители" просто переходят в wait. так как

@Override
    public void run() {
        try {
            while (true) {
               List<SimpleContent> docs = queue.take();
                ...
             }
        }
     }

Как сделать так, чтобы остановить main и по завершению ArrayBlockingQueue main продолжал работу?

public static void main(String[] args) {
    for (QueueProps queueProps : queues) {
        BlockingQueue<List<SimpleContent>> blockingQueue = new ArrayBlockingQueue(1);
        QueuePerformer queuePerformer = new QueuePerformer(blockingQueue);
        queuePerformer.setName(queueProps.getQueueSuffix());
        queuePerformer.start();
        QueueSender queueSender = new QueueSender(blockingQueue);
        queueSender.setName(queueProps.getQueueSuffix());
        queueSender.start();
    }
    setTime();
    //и так далее......
}
Answer 1

Используйте для этого ExecutorService и Callable вот вам простой пример

public static void main(String[] args) throws InterruptedException {
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    List<Callable<String>> todo = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        todo.add(new Task());
    }
    List<Future<String>> results = executorService.invokeAll(todo);
    System.out.println("Finished...");
}
static class Task implements Callable<String> {
    @Override
    public String call() throws Exception {
        Thread.sleep(5000);
        System.out.println(Thread.currentThread().getName() + " finished.");
        return "some-data";
    }
}

Вот результат этой программы:

pool-1-thread-1 finished.

pool-1-thread-2 finished.

pool-1-thread-3 finished.

pool-1-thread-4 finished.

pool-1-thread-5 finished.

pool-1-thread-6 finished.

pool-1-thread-7 finished.

pool-1-thread-8 finished.

pool-1-thread-9 finished.

pool-1-thread-10 finished.

Finished...

Как написано в JavaDocs к методу invokeAll() - Выполняет все задачи, возвращает список Futures которые хранят в себе статус и результаты когда все выполняться.

PS если вам не надо получать данные из потоком имплементируйте интерфейс Runnable вместо Callabe и обверните все это так:

Executors.callable(new Task());
Answer 2

Выполните join() метод класса Thread, чтобы подождать, пока поток завершит свое выполнение.

queuePerformer.join();
queueSender.join();
READ ALSO
JSON and JAVA (android)

JSON and JAVA (android)

в моем приложения (андроид) я получаю с сервера jsonПосле при оброботке

174
Physicaloid library Arduino + Android

Physicaloid library Arduino + Android

Никак не могу разобраться как создать цикл чтения Serial Monitor'a при помощи библиотеки Physicaloid libraryА выход из этого цикла должен совершаться только...

248
Telegram bot Java Heroku deploy

Telegram bot Java Heroku deploy

Доброго вечераВопрос следующий

484