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

时间:2018-06-01 10:36:52

标签: java multithreading

我有以下代码,它运行在一个简单的主要活动上:

 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();
                }
        }
    });

应用程序终止就好了。为什么呢?

4 个答案:

答案 0 :(得分:2)

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();

答案 1 :(得分:1)

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()

答案 2 :(得分:1)

  

执行程序线程在主类完成后继续运行

是的,它的目的是为了做到这一点。 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);

关闭池和已提交完成的作业后,池中的线程将终止,如果没有更多非守护程序线程,则应用程序将停止。

答案 3 :(得分:0)

  • 原因

:您没有关闭执行程序。当您关闭时,请注意在终止后执行此操作

  • 解决方案

    :仅在使用简单代码终止后才关闭它。

例如:

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

  • 另一个解决方案是使用ExecutorCompletionService,如果你想完成任务,你需要一个ExecutorCompletionService。这充当了BlockingQueue,允许您在完成任务时轮询它们。
相关问题