【问题标题】:Best practice for executing large number of tasks [duplicate]执行大量任务的最佳实践[重复]
【发布时间】:2017-07-05 11:01:21
【问题描述】:

下面的代码在循环中创建了大量的可运行对象,甚至只有 5 个线程来处理任务。有什么办法可以让内存中随时只有 5 个可运行对象而不是任务总数(100000)。

ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10000; i++) {
    Runnable worker = new WorkerThread("" + i);
    System.out.println("ExecutorExample.main()");
    executor.execute(worker);
}

【问题讨论】:

  • 创建 5,提交,等待完成,然后再次创建 5,等等,直到你有 10000 ??
  • 创建一个ExecutorServce 来管理其他五个服务并分配新的作业,这样您的主线程就不会挂起。

标签: java concurrency java.util.concurrent


【解决方案1】:

在任何时候只有 5 个可运行对象将出现在内存中的要求过于严格。当一个任务完成时,将没有下一个任务要运行,并且会花费一些时间来创建另一个任务。最好有 5 个运行任务和 5 个排队等待。为了限制队列中任务的数量,对可运行对象使用固定大小的 BlockingQueue,例如

ThreadPoolExecutor executor = new ThreadPoolExecutor(
     5, 5,
     10L, TimeUnit.MILLISECONDS,
     new LinkedBlockingQueue<Runnable>(5)
)

UPDT 为避免 RejectedExecutionException,添加 RejectedExecutionHandler,如 https://stackoverflow.com/a/3518588/1206301 中所建议的:

RejectedExecutionHandler block = new RejectedExecutionHandler() {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            try {
                executor.getQueue().put(r);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    executor.setRejectedExecutionHandler(block);

【讨论】:

  • 你能告诉我如何在上面的场景中使用它。
  • @SandeepBhardwaj 只需将程序中的第一行替换为我建议的内容,其余部分保持不变。
  • 由于Exception in thread "main" java.util.concurrent.RejectedExecutionException...而只运行了10个任务
  • 可能值得强调您所指的帖子中的引述:“现在。这是一个非常糟糕的主意,原因如下”(给出了 3 个),然后是“但是,有时是一种阻止策略,尽管存在所有固有风险,但确实是您想要的”。或者你不同意那里给出的不使用它的理由?
  • @starikoff 我实际上并不认为这个想法是那么糟糕。对于给定的用例,它运行良好。
猜你喜欢
  • 2013-09-18
  • 1970-01-01
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
  • 1970-01-01
相关资源
最近更新 更多