简体   繁体   English

主类完成后,执行器线程继续运行

[英]Executor thread keeps running after main class is finished

I have the following code which runs on a simple main activity: 我有以下代码在一个简单的主要活动上运行:

 Executor executor = Executors.newFixedThreadPool(1);
    executor.execute(new Runnable() {
      public void run() {
        try {

            System.out.println("sleep");
            Thread.sleep(5000); 



        } catch (InterruptedException e) {
          System.out.println("Interrupted, so exiting.");
        }
      }
    });

It looks like that when i run this code application doesnt terminate and nothing gets printed either (except the first sleep). 看起来当我运行此代码应用程序时,它不会终止,也不会打印任何内容(第一次睡眠除外)。

On the other hand when i run this: 另一方面,当我运行此命令时:

 Thread t = new Thread(new Runnable() {
        public void run() {
             try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    });

application terminates just fine. 应用程序终止就好了。 Why? 为什么?

Executor interface would not allow you to shutdown the service. 执行程序界面不允许您关闭服务。 Preferred way is to use ExecutorService instead of Executor 首选方法是使用ExecutorService而不是Executor

ExecutorService executorService =  Executors.newSingleThreadExecutor(factory);
  executorService.execute(new Runnable() {
   @Override
   public void run() {
    try {
     doTask();
    } catch (Exception e) {
     logger.error("indexing failed", e);
    }
   }
  });
  executorService.shutdown();
Thread t = new Thread(new Runnable() {
    public void run() {
         try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }
});

With this, the thread will terminate after executing the run method. 这样,线程将在执行run方法后终止。

Runnbale r = ...
Executor executor = Executors.newFixedThreadPool(1);
executor.execute(r);

With this, the executor will create a thread which works like below: 这样,执行程序将创建一个如下所示的线程:

new Thread(new Runnable() {
    @Override
    public void run() {
        while(notShutdown()) {
            waitingForTask(); // may get blocked
            runTask(); // execute Runnable user submits
        }
    }
});

This thread will not terminate after the first task, it will keep waiting for new tasks. 该线程不会在第一个任务之后终止,它将继续等待新任务。 You need call executor.shutdown() explicitly. 您需要显式调用executor.shutdown()

Executor thread keeps running after main class is finished 主类完成后,执行器线程继续运行

Yep, it's designed to do that. 是的,它是专为此目的而设计的。 The whole point of an ExecutorService is that there is a pool of threads. ExecutorService的全部要点是有一个线程池。 Even though the Runnable that you submitted has finished, the threads in the pool are waiting for other jobs to come along. 即使您提交的Runnable已完成,池中的线程仍在等待其他作业的到来。 You need to shutdown the pool to get your application to terminate. 您需要关闭池以使应用程序终止。

It looks like that when i run this code the application doesn't terminate and nothing gets printed either (except the first sleep). 看起来当我运行此代码时,应用程序不会终止,也不会打印任何内容(第一次睡眠除外)。

The right way to use the ExecutorService is something like the following: 使用ExecutorService的正确方法如下所示:

ExecutorService threadPool = Executors.newFixedThreadPool(1);
threadPool.submit(new Runnable() ...);
// submit any other jobs to the pool here
...
// after last submit, you shutdown the pool, submitted jobs will continue to run
threadPool.shutdown();
// optionally wait for all jobs to finish in pool, similar to thread.join()
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);

Once you shutdown the pool and the jobs that have submitted finish, the threads in the pool will terminate and, if there are no more non-daemon threads, your application will stop. 关闭池并完成提交的作业后,池中的线程将终止,并且如果没有更多的非守护线程,则您的应用程序将停止。

  • Cause 原因

: You did not shutdown the executor .And When you do the shutdown be aware to do it after it's termination :您没有关闭执行程序。执行关闭操作时,请注意在终止后执行该操作

  • Solution

    : shut it down only after its termination using a simple code. :仅在终止后使用简单代码将其关闭。

For example : 例如 :

executor.shutdown(); while (!executor.isTerminated()) {}

  • Another solution is to use ExecutorCompletionService if you want to take tasks as they complete you need an ExecutorCompletionService. 如果要在完成任务时执行任务,则需要ExecutorCompletionService,这是另一种解决方案,即使用ExecutorCompletionService。 This acts as a BlockingQueue that will allow you to poll for tasks as and when they finish. 这充当BlockingQueue,可让您在完成任务时轮询任务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM