如何在Java中创建一个不能同时运行某些任务的线程池?

时间:2018-11-19 10:52:43

标签: java multithreading

我想将任务提交到线程池(或执行服务),但是如果执行器中已经有一个具有相同密钥的任务,则不应同时执行任务。

特别是,这是针对构建工具的,以防止源树的同一部分的任务同时执行。

这是为什么我想要这种行为的一个示例:

public class Example {

    public static void main(String[] args) throws Exception {

        ExecutorService service = Executors.newFixedThreadPool(2);

        Path resource = Paths.get("tmp");

        service.submit(() -> {
            Files.write(resource, Collections.singleton("foo"));
            Thread.sleep(10);

            if (!new String(Files.readAllBytes(resource)).equals("foo")) {
                System.err.println("someone changed my stuff");
            }


            return null;
        });
        service.submit(() -> Files.write(resource, Collections.singleton("bar")));
        service.shutdown();
        service.awaitTermination(1, TimeUnit.MINUTES);
    }
}

2 个答案:

答案 0 :(得分:1)

解决方案是为每个密钥使用单独的单线程执行程序。由于可以存在许多密钥,因此为每个密钥创建线程可能会很昂贵,因此我们用轻量级SerialExecutor代替了单线程执行程序,该行为的行为类似于单线程执行程序,但没有自己的线程,因此需要时,来自某些普通后端执行程序的线程。 JavaDocs of Executor中描述了SerialExecutor。最佳版本可在我的CodeSamples project

中找到

看到类似的问题Design pattern to guarantee only one Runnable object of particular id value is being executed by the pool

答案 1 :(得分:0)

尝试使用2个不同的执行程序来执行不同类型的任务,如果第一个缓冲池已完成,请再启动一个。

ExecutorService executor1 = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
     Runnable worker = new FirstTask("" + i);
         executor1.execute(worker);
     }
     executor1.shutdown();

  while (!executor.isTerminated()) {
    }

ExecutorService executor2 = Executors.newFixedThreadPool(5);
    for (int i = 0; i < 10; i++) {
         Runnable worker = new AnotherTask("" + i);
             executor2.execute(worker);
    }
    executor2.shutdown();