Как дождаться завершения одного из запущенных потоков в ExecutorService для назначения другой задачи - PullRequest
0 голосов
/ 07 июня 2018

У меня есть цикл, который назначает задачу для ExecutorService с потоком фиксированного размера, я хочу, чтобы основная программа ждала , чтобы threadPool освободил один из своих потоков, чтобы назначить ему другую задачу.

Вот мой пример кода: в этом примере кода я хочу, чтобы finished! был напечатан в конце, и хочу использовать ExecutorService.

public static void main(String[] args) {
    ExecutorService ex = Executors.newFixedThreadPool(3);


    for(int i=0; i< 100; i++) {

        ex.execute(new TestThread(i)); // I want the program wait here for at least one thread to free

    }

    System.out.println("finished!");
}

private static class TestThread implements Runnable {

    private int i;
    public TestThread(int i) {
        this.i = i;
    }

    @Override
    public void run() {

        System.out.println("hi: " + i);
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Я понимаю, что вы хотите, чтобы поток, отправляющий задание, блокировался в случае, когда в службе исполнителя нет свободного, легкодоступного рабочего потока.Это может быть полезно для применения противодавления.

В основном служба исполнителя «просто» состоит из очереди исполняемых объектов и пула рабочих потоков.

Вы можете получитьэто происходит путем создания службы исполнителя с рабочей очередью фиксированного размера (в вашем случае, размером один).

В коде: (обратите внимание, что поток вызывающих абонентов все еще продолжится после отправки последнего задания;не будет ждать завершения этой работы)

package stackOv;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class BackPressure {
    public static void main(String[] args) {
        // this is the backing work queue; in this case, it is of bounded size
        ArrayBlockingQueue<Runnable> q = new ArrayBlockingQueue<>(1);
        ExecutorService ex = new ThreadPoolExecutor(3, 3, 30, TimeUnit.SECONDS, q,
                new ThreadPoolExecutor.CallerRunsPolicy());
        for(int i=0; i< 100; i++) {
            ex.execute(new TestWork(i));
        }
        System.out.println("finished!");
    }

    private static class TestWork implements Runnable {
        private int i;
        public TestWork(int i) {
            this.i = i;
        }
        @Override
        public void run() {
            System.out.println("hi: " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) { e.printStackTrace(); }
        }
    }
}
0 голосов
/ 07 июня 2018

Все, что вам нужно, это:

ex.awaitTermination();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...