当前位置: 首页 > 知识库问答 >
问题:

如何将Java ExecutorService线程池用于正在进行的/无限的任务?

斜俊
2023-03-14

JavaExecutorService框架允许您使用托管线程池委托要执行的多个任务,以便一次可以执行N个任务X个任务,直到完成。

我的问题是。。。如果N是一个无限大的数字,或者太大以至于最初无法分配/分配/定义,该怎么办。

如何利用Java(ExecutorService)中的线程池概念来处理比合理提交更多的任务,而不会耗尽资源。

为了回答这个问题,假设每个任务都是自包含的,不依赖于任何其他任务,并且任务可以按任意顺序完成。

我最初尝试解决这个问题时涉及一次提供ExecutorService Y线程,但我很快意识到没有明显的方法来判断特定任务何时完成,因此提交要执行的新任务。

我知道我可以编写自己的“ExecutorService”,但我正试图利用Java框架已经提供的丰富资源。我通常属于“不要重新发明轮子”这一类,因为比我更伟大的头脑已经为我投资了。

提前感谢任何能够提供有关如何解决此类问题的见解的人。

共有2个答案

贡念
2023-03-14

使用java。util。同时发生的使用java的ThreadPoolExecutor。util。同时发生的ArrayBlockingQueue作为其工作队列。通过这种方式,尝试放置比队列大小阻止的任务更多的任务。

  BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<Runnable>(100);
  ThreadPoolExecutor tpe=new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, workQueue);

  while (true) {
     tpe.execute(createNewTask());
  }
弘阳德
2023-03-14

您可以使用CompletionService来完成此操作。您可以使用一个线程来为服务播下一系列任务,然后在任务完成后,您可以添加新的任务。

一个简单的例子:

final CompletionService service = new ExecutorCompletionService(Executors.newFixedThreadPool(5));
Runnable taskGenerator = new Runnable() {
    public void run() {
        // Seed the service
        for (int i = 0; i < 100; ++i) {
            service.submit(createNewTask());
        }
        // As tasks complete create new ones
        while (true) {
            Future<Something> result = service.take();
            processResult(result.get());
            service.submit(createNewTask());
        }
    }
};
new Thread(taskGenerator).start();

这将使用一个线程池执行器(ThreadPoolExecutor)和5个线程来处理任务,并使用一个手动滚动的生产者/消费者线程来生成任务和处理结果。

很明显,您会想要比更智能的东西,而(true),您需要对processResult和createNewTask进行合理的实现,并且这假设任务执行比生成它们或处理结果慢得多。

希望这能让你走上正轨。

 类似资料:
  • 我正在创建一个可以监视100-150个设备的监视应用程序...现在要设计一个监视器应用程序,我有两种方法: > < li> 为每个要监控的设备创建一个线程,每个线程将ping(使用ICMP)设备以了解设备是否在线。这些线程将无限期地运行,以便在特定的时间间隔(比如60秒)后了解它们的状态。 创建一个线程池,并为每个设备提交一个任务到一个线程池。任务是简单地 ping 到设备。因此,在当前设计中,任

  • 问题内容: 现在我想在进入for循环之前集中所有任务,但是当我运行此程序时,for循环会在此之前执行并引发此异常: 问题答案: 一种工作方式是,当您调用它时,它等待所有任务完成: 执行给定的任务,并在所有任务完成时返回保存其状态和结果的期货列表。Future.isDone()对于返回列表的每个元素为true。 请注意,已完成的任务可能已正常终止或引发了异常而终止 。如果在进行此操作时修改了给定的集

  • 我有一个关于关闭WINAPI线程池的问题。 假设我已经使用清理组初始化了一个线程池,并使用SubmitThreadpoolWork将一些任务推送到线程池。我正在任务的回调函数中调用CloseThreadPoolask。 目前,线程池的队列中有正在执行的任务和挂起的其他任务。 现在,为了关闭线程池,我想使用CloseThreadpoolCleanupGroup成员函数,而不挂起队列任务来完成,但我仍

  • 问题内容: 我有一个命令,该命令使用git从Linux Shell将文件上传到远程服务器,这将需要许多小时才能完成。 如何将正在运行的程序放在后台?这样我仍然可以在Shell上工作并且该过程也可以完成? 问题答案: 使用CTRL + Z暂停该过程,然后使用命令在后台将其恢复。例如: 手册页中有关作业控制和使用的更多信息: 作业控制在进程运行时 键入 暂停 字符(通常为^ Z,Control-Z)将

  • 问题内容: 我在Java中使用A 来管理许多正在运行的线程。我创建了自己的简单名称,以便为线程命名。 问题在于,在首次创建线程池时会在线程中设置名称,并且该名称与线程池实际正在运行的任务无关。我了解这一点…尽管我的Runnable和Callables具有名称,但它们实际上是从的运行线程开始的抽象层。 关于为线程池创建名称,StackOverflow上还有其他一些问题。(请参阅如何为可调用线程命名?