【问题标题】:Using ExecutorService but stopping after submitted tasks executed使用 ExecutorService 但在提交的任务执行后停止
【发布时间】:2021-02-26 00:02:01
【问题描述】:

执行者即使完成了执行任务也不会停止

    Here am calling awaitTermination to wait until all executing tasks to be completed here the problem is, it's not terminating executor service for a long time, once stopping server then only getting InterruptedException otherwise it's waiting until unless we are stopping the server, not sure what am missing here, is this reason  Long.MAX_VALUE, TimeUnit.MILLISECONDS its not terminates even completed submitted tasks? Thanks.

<pre><code>
      executorService.shutdown();
      try {
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
</code></pre>

【问题讨论】:

  • 你向执行者服务提交了哪些任务?他们显然需要很长时间。您可以编译一个与您的实际项目分开minimal reproducible example,然后将其添加到您的问题中吗?
  • 这是我的全部代码,我作为答案发布了

标签: java multithreading executorservice


【解决方案1】:

您没有提供足够的细节来确定您的问题。所以这里有一个与你类似的工作代码的完整示例。

提示:在嵌入 JSP 之前,让您的代码像普通 Java 一样工作。

常规语法

首先我们使用当今 Java 的传统语法。

代码关键部分:

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for ( int i = 0 ; i < 7 ; i++ )
        {
            executorService.submit( new PrintUuid() );
        }
        executorService.shutdown();
        try { executorService.awaitTermination( Long.MAX_VALUE , TimeUnit.MILLISECONDS ); } catch ( InterruptedException e ) { e.printStackTrace(); }

一个完整的示例应用程序。

package work.basil.example.simple;

import java.time.Duration;
import java.time.Instant;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class App
{
    public static void main ( String[] args )
    {
        App app = new App();
        app.demo();
    }

    private void demo ( )
    {
        System.out.println( "INFO - End of `demo` method. " + Instant.now() );

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for ( int i = 0 ; i < 7 ; i++ )
        {
            executorService.submit( new PrintUuid() );
        }
        executorService.shutdown();
        try { executorService.awaitTermination( Long.MAX_VALUE , TimeUnit.MILLISECONDS ); } catch ( InterruptedException e ) { e.printStackTrace(); }

        System.out.println( "INFO - End of `demo` method. " + Instant.now() );
    }

    class PrintUuid implements Runnable
    {
        @Override
        public void run ( )
        {
            try { Thread.sleep( Duration.ofSeconds( 2 ).toMillis() ); } catch ( InterruptedException e ) { e.printStackTrace(); }
            UUID uuid = UUID.randomUUID();
            System.out.println( "uuid = " + uuid + " at " + Instant.now() + " by thread ID # " + Thread.currentThread().getId() );
        }
    }
}

作为调试的一部分,让该代码完全按照编写的方式在您的应用中运行。然后过渡到您的实际任务以同时运行。一切正常后,将代码移动到您的 JSP 中。

织机项目

Project Loom 将带来 Java 并发设施的创新。基于早期访问 Java 17 的实验性构建是 available now

正在考虑的更改之一是使ExecutorService 接口AutoCloseable。这意味着我们可以使用try-with-resources 语法。只有在所有提交的任务都完成后,控制流才会通过try 块。

一个较小的变化是对 java.time 类的支持。这包括在休眠当前线程时使用Duration 替代int 毫秒计数。

package work.basil.example.simple;

import java.time.Duration;
import java.time.Instant;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class App
{
    public static void main ( String[] args )
    {
        App app = new App();
        app.demo();
    }

    private void demo ( )
    {
        System.out.println( "INFO - End of `demo` method. " + Instant.now() );

        try (
                ExecutorService executorService = Executors.newSingleThreadExecutor() ;
        )
        {
            for ( int i = 0 ; i < 7 ; i++ )
            {
                executorService.submit( new PrintUuid() );
            }
        }
        // At this point, flow-of-control blocks until all submitted tasks are done/canceled/failed.
        // After this point, the executor service will have been automatically shutdown, wia `close` method called by try-with-resources syntax.

        System.out.println( "INFO - End of `demo` method. " + Instant.now() );
    }

    class PrintUuid implements Runnable
    {
        @Override
        public void run ( )
        {
            try { Thread.sleep( Duration.ofSeconds( 2 ) ); } catch ( InterruptedException e ) { e.printStackTrace(); }
            UUID uuid = UUID.randomUUID();
            System.out.println( "uuid = " + uuid + " at " + Instant.now() + " by thread ID # " + Thread.currentThread().getId() );
        }
    }
}

【讨论】:

  • 这是我的全部代码,我作为另一个答案发布了
【解决方案2】:

这是我的总代码

public void processActivityDeposits(
    Activity activity) {
  int partitionSize =
      environment.getProperty("patition.size", Integer.class, 1000);
  List<Long> records =
      service.findReadyToProcessRecords(
          activity.getActivityId(),
          partitionSize);
  if (records != null && records.size() > 0) {
    try {
      int threadPoolSize =
          environment.getProperty("thread.pool.size", Integer.class, 10);
      ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
      for (Long activityId : records) {
        executorService.execute(
            new ActivityDepositInternalProcessor(
                activityId));
      }
      executorService.shutdown();
      try {
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      processActivityDeposits(
          activity);
    } catch (Exception exception) {
      exception.printStackTrace();
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多