如何等待ExecutorService中的一个正在运行的线程完成分配另一个任务

时间:2018-06-07 07:59:51

标签: java multithreading thread-safety threadpool java-threads

我有循环,将任务分配给具有固定大小线程的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 :(得分:1)

我理解你想要提交作业的线程,在执行者服务中没有免费的,随时可用的工作线程的情况下阻止。这可以用于施加背压。

核心执行程序服务“简单地”由可运行队列和工作线程池组成。

您可以通过使用固定大小的工作队列构建执行程序服务来获得此行为(在您的情况下,大小为1)。

在代码中:(请注意,您的调用者线程在提交上一个作业后仍将继续;它不会等待该作业完成)

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

答案 1 :(得分:-1)

您只需要:

val file = uri.toFile()