簡體   English   中英

主類完成后,執行器線程繼續運行

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

我有以下代碼在一個簡單的主要活動上運行:

 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.");
        }
      }
    });

看起來當我運行此代碼應用程序時,它不會終止,也不會打印任何內容(第一次睡眠除外)。

另一方面,當我運行此命令時:

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

應用程序終止就好了。 為什么?

執行程序界面不允許您關閉服務。 首選方法是使用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();
            }
    }
});

這樣,線程將在執行run方法后終止。

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

這樣,執行程序將創建一個如下所示的線程:

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

該線程不會在第一個任務之后終止,它將繼續等待新任務。 您需要顯式調用executor.shutdown()

主類完成后,執行器線程繼續運行

是的,它是專為此目的而設計的。 ExecutorService的全部要點是有一個線程池。 即使您提交的Runnable已完成,池中的線程仍在等待其他作業的到來。 您需要關閉池以使應用程序終止。

看起來當我運行此代碼時,應用程序不會終止,也不會打印任何內容(第一次睡眠除外)。

使用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);

關閉池並完成提交的作業后,池中的線程將終止,並且如果沒有更多的非守護線程,則您的應用程序將停止。

  • 原因

:您沒有關閉執行程序。執行關閉操作時,請注意在終止后執行該操作

  • :僅在終止后使用簡單代碼將其關閉。

例如 :

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

  • 如果要在完成任務時執行任務,則需要ExecutorCompletionService,這是另一種解決方案,即使用ExecutorCompletionService。 這充當BlockingQueue,可讓您在完成任務時輪詢任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM