【问题标题】:Waiting for threads to complete in a executor service在执行器服务中等待线程完成
【发布时间】:2014-05-10 00:10:00
【问题描述】:

我已经用 N 个线程初始化了一个 exectuor 服务。在 N 个线程完成后,我想等待一段时间,然后用 N 个线程的新实例重用执行器。我该怎么做?

这是我正在使用但失败的示例代码:

       int NumberOfThreads=Integer.parseInt(PropertyHandler.getProperty("numberOfThreads"));

       ExecutorService executor = Executors.newFixedThreadPool(NumberOfThreads);
       log.info("Executor class has been initialized");
       while (true) {

        jobStack = MrMestri.buildJobs();
        log.info("Creating a job stack of the search urls");
        if (jobStack.isEmpty()) 
        {
           Thread.sleep(10000);
        } 
        else {
           int jobToken = 0;
           while (jobStack.size() > 0) {
           jobToken++;
           MrRunnable worker = new MrRunnable(jobStack.pop());
           executor.execute(worker);
           if (jobToken% Integer.parseInt(PropertyHandler.getProperty("totalTrends")) == 0)       {
           log.info("All jobs for the clock cycle complete , waiting for next clock cycle to start. Number of jobs completed " + jobToken);
           executor.shutdown();
           Thread.sleep(milliseconds);

}

现在我正在使用 executor shutdown ,没有 executor 来执行我的线程。而且我的线程实现了可运行。

任何快速响应都会有很大帮助。谢谢。

【问题讨论】:

  • 可能是 executor.awaitTermination ?
  • 当你使用 executor.shutdown() 时使用等待终止。或者至少它看起来像什么或什么时候超时。我不知道我可以在那里设置什么时间,因为我的一些回复可能需要时间。所以我不认为我想走那条路。

标签: java multithreading executorservice


【解决方案1】:

问题出在while 循环内的下面一行。

jobStack = MrMestri.buildJobs();

在这种情况下,以下条件将始终返回 false,因为如果您想处理下 N 个任务,jobStack 永远不会为空

jobStack.isEmpty()

如果条件满足,则将此条件移动到内部while 循环和break 内部循环中以处理接下来的N 个任务。


示例代码:

import java.util.Stack;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Executor {

    /**
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        int NumberOfThreads = Integer.parseInt("10");

        ExecutorService executor = Executors.newFixedThreadPool(NumberOfThreads);
        while (true) {

            Stack<Job> jobStack = MrMestri.buildJobs();
            int jobToken = 0;
            while (true) {
                if (jobStack.size() > 0) {
                    jobToken++;
                    MrRunnable worker = new MrRunnable(jobStack.pop());
                    executor.execute(worker);
                    if (jobToken % Integer.parseInt("4") == 0) {
                        // executor.shutdown();
                        System.out.println("short waiting...");
                        Thread.sleep(2000);

                    }
                } else {
                    System.out.println("long waiting...");
                    Thread.sleep(10000);
                    break;
                }
            }
        }
    }
}

class MrMestri {

    public static Stack<Job> buildJobs() {
        Stack<Job> stack = new Stack<Job>();
        stack.push(new Job("A"));
        stack.push(new Job("B"));
        stack.push(new Job("C"));
        stack.push(new Job("D"));
        stack.push(new Job("E"));
        stack.push(new Job("F"));
        return stack;
    }

}

class MrRunnable implements Runnable {
    private Job job;

    public MrRunnable(Job j) {
        job = j;
    }

    @Override
    public void run() {
        System.out.println(job.getName());
    }
}

class Job {
    private String name;

    public Job(String n) {
        name = n;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

【讨论】:

  • 谢谢,我认为循环的这种用法很棒。我从来没有这样想过。不得不退后一步查看我的代码!太棒了!
  • 这解决了原始代码中的一个问题,但不是等待线程完成的正确方法。无论出现什么问题,几乎总有比调用 Thread.sleep 更好的方法。请参阅下面的 invokeAll 答案。
  • 但我确实需要它来睡觉对吧?如果所有线程都已完成,invokeall 会让我知道,但在那之后我仍然需要使用线程睡眠。那么上面给出的方法还是不对吗?
  • 还要检查外部while 循环。如果jobStack 是空的,那么从外部while 循环中走出来就很简单。
  • 正是我现在所做的:)
【解决方案2】:

只是不要关闭您的执行程序 - 而是重复使用它。 生成 Callable 任务集合而不是 Runnable 并使用:

executor.invokeAll

它将执行所有任务并在所有任务完成后立即返回。 如果 MrRunnable 不是你的类或者由于任何原因它必须实现 Runnable 你可以简单地将它转换为 Callable 像:

new Callable<Void>()
    {
        @Override
        public Void call() throws Exception {
            worker.run();
            return null;
        }
    };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多