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

在Java中,当executorservice可能向自己提交额外任务时,如何关闭executorservice

洪德寿
2023-03-14

> 在将所有内容提交给service1后,

  • shutdown()service1
  • 上调用
  • 则在shutdown()之前提交的所有任务都实际完成运行之前,awaitTermination()才返回。--shutdown()然后在service2上调用,但是由于提交给service1的所有任务都已完成,并且从service1上的任务中提交给service2的所有任务都已提交给service2,所以在service2上调用shutdown()之前,所有任务都已提交给service2。--对于service3以此类推

    ExecutorService[] services = {
            service1,
            service2,
            service3};
    
    int count = 0;
    for(ExecutorService service: services)
    {   
        service.shutdown();
        service.awaitTermination(1, TimeUnit.HOURS);
    }
    

    但是,我现在添加了这样一种情况,即service2可以将datapacket分解成一个较小的包,并在service2上提交额外的任务,而代码现在失败了。问题是,Service1上的所有任务完成后,Service2将调用Shutdown(),但现在我们希望从Service2中运行的任务中提交其他Service2任务

    我的问题:

    1. shutdown()是在所有提交的任务完成运行后重新运行,还是立即返回,但不停止已提交的任务的运行?更新:在下面回答
    2. 如何解决新问题?
  • 共有1个答案

    钮兴安
    2023-03-14

    “shutdown”只是告诉池不要接受任何更多的工作。它什么也不做了。所有已提交的工作将正常执行。当队列耗尽时,池实际上会破坏它的所有线程并终止。

    这里的问题是,service2中的任务将向service2提交额外的任务进行处理。似乎没有办法知道什么时候应该真正调用关机。但是,唉,还有一个替代方案,假设这些较小的数据包不会进一步分解为服务。

    List<Future<Void>> service2Futures = new ArrayList<Future<Void>>();
    
    service2Futures.add(service2.submit(new Callable<Void>() {
      public Void call() throws Exception {
        // do your work, submit more stuff to service2
        // if you submit Callables, you could use Future.get() to wait on those
        // results.
        return null;
      }
    }));
    
    for (Future<Void> future : service2Futures) {
      future.get();
    }
    
    service2.shutdown();
    ...
    

    这里发生的事情是,您要为顶级提交的任务存储未来的对象(您必须使用可调用的而不是可运行的)。不是在提交后立即关闭池,而是简单地收集未来的对象。然后,通过循环遍历它们,并对每个都调用get(),直到它们都运行完毕。“get()”方法将阻塞,直到运行该任务的线程完成为止。

    ForkJoinPool forkJoinPool = new ForkJoinPool();
    RecursiveAction action = new RecursiveAction() {
        protected void compute() {
             // break down here and build actions
             RecursiveAction smallerActions[] = ...; 
             invokeAll(smallerActions);
        }
    };
    
    Future<Void> future = forkJoinPool.submit(action);
    
     类似资料:
    • 我将可调用任务(使用submit())提交给ExecutionService的实现。有时我似乎遇到了死锁,但无法工作在哪里或为什么会发生,所以我想为任务设置一个超时,我不清楚是如何做到的? 我应该吗 在提交任务时,在ExecutionService上使用invokeAny()而不是submit()并设置超时。我使用submit()一次提交许多任务,我是否也可以这样使用invokeAny(),我很谨

    • 我正在尝试将一个任务提交给Java的ExecutorService。它要么需要一个Callable,它允许抛出异常,要么需要一个Runnable。我的用例是愚蠢的:我想安排一个抛出异常的任务,但它是一个无效的方法。因此,我不能使用Callable或Runnable,因为方法定义与我的用例不匹配。我还想让我的异常从提交后收到的Future传播。有什么想法吗?

    • 使用,我提交了一批任务,任务有一个时间变量,即之间的共享。我想在提交任务之前设置的值。代码如下: 但它出错了 我该怎么解决?

    • 我有一个简单的java,它运行一些任务对象(实现)。 除了尽最大努力尝试停止处理正在执行的任务之外,没有任何保证。例如,典型的实现将通过{@link thread#interrupt}取消,因此任何未能响应中断的任务都可能永远不会终止。 我的问题是,有没有办法确保那些(任务)线程会终止?我想出的最佳解决方案是在程序末尾调用,但这显然是愚蠢的。

    • 要并行或异步运行一些东西,我可以使用ExecutorService:

    • 本文向大家介绍postgresql 如何关闭自动提交,包括了postgresql 如何关闭自动提交的使用技巧和注意事项,需要的朋友参考一下 postgresql中默认是自动提交的 查看是否是自动提交: 关闭自动提交: 另一种方式就在会话开始的时候以begin开始相当于关闭了自动提交,以end或者commit结束就可以了 补充:pg(hgdb)默认事务自动提交 默认情况下,AUTOCOMMIT(自动