【问题标题】:How do I load processes from queue and have a new process start when one finishes in Java?如何从队列中加载进程并在 Java 中完成一个新进程时启动一个新进程?
【发布时间】:2020-03-24 19:08:12
【问题描述】:

假设我有一个 Process 对象队列,它将在我的计算机上执行一个程序,而不是单线程。为了提高效率,我想一次运行 4 个实例,以便充分利用我的 4 核 CPU。如何从队列中取出 4 个元素,开始处理它们,并让队列中的新进程取代已完成运行的进程?

【问题讨论】:

  • 使用Executors.newFixedThreadPool(4) 并在其中提交您所有的Processes。它有自己的队列。
  • @Kayaman 从我在 Javadoc 中看到的 newFixedThreadPool(4) 将返回一个 ExecutorService 对象。 ExecutorService.submit() 将实现Runnable 接口的对象作为参数。进程对象不实现Runnable 接口,但Thread 对象实现。由于在我的情况下我看不到Thread 对象执行像FFmpeg 这样的本机二进制文件的任何方法,我想我需要创建自己的对象来实现Runnable 并让它使用Runtime.exec() 来运行FFmpeg 并通过到ExecutorService.submit()。听起来对吗?
  • 是的,您可以(必须)将您的Process 包装成Runnable(或Callable,如果您需要返回结果)。比如executor.submit(() -> process.doSomething());循环。

标签: java parallel-processing process queue


【解决方案1】:

执行器框架

Java 为您提供了所有这些功能。您无需创建 Process 类或队列。

您的每个任务都应实现RunnableCallable 接口。

按照Oracle tutorial 中的说明,将这些提交给执行服务部门。执行器服务充当您的队列,将提交的任务提供给可用线程。

要监控任务的完成情况,您可以捕获返回的Future 对象。

如果您希望最多同时运行四个任务,请使用包含四个线程的后备线程池创建您的执行器服务。

但要小心过度安排。对于四核机器,如果您的任务是 CPU 密集型的,您可能希望使用少于四个线程。您的计算机还有其他工作要做,例如操作系统任务、运行 JVM 和运行其他应用程序。另一方面,如果您的任务不是 CPU 密集型的,因此它们花费大量时间等待(例如等待网络调用返回),那么您可能需要更大的线程池。

所有这些都已经在 Stack Overflow 上介绍过很多次了。因此,搜索以了解更多信息。

请务必阅读 Goetz 等人的Java Concurrency In Practice一书。

【讨论】:

    猜你喜欢
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 2018-11-15
    • 2015-03-22
    • 2021-02-25
    • 1970-01-01
    • 2012-06-30
    相关资源
    最近更新 更多