执行者服务 - 不阻止主程序

时间:2016-05-11 03:46:26

标签: java multithreading threadpool executorservice

我正在使用ExecutorService并阻止主程序一段时间,但我不想阻止主程序。

以下是代码:

public class Test {

    public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
        ExecutorService executor = null;

        try {
            executor = Executors.newFixedThreadPool(1);

            System.out.println("Start 1");
            Runnable task = new Runnable() {
                public void run() {
                    System.out.println("Start 2");
                    try {
                        Thread.sleep(7000);
                        System.out.println("Start 5");

                    } catch (Exception e) {

                    }
                }
            };
            System.out.println("Start 3");

            // executor.execute(task);
            Future future = executor.submit(task);
            Object result = future.get(9, TimeUnit.SECONDS);
            System.out.println("Start 4");

        } catch (Exception e) {

        } finally {
            System.out.println("finally");
            executor.shutdownNow();
        }

    }
}

输出:

Start 1
Start 3
Start 2
Start 5
Start 4
finally

目前除非线程完成执行,否则它不会打印Start 4。我正在寻找的是一些机制,我们可以有一个超时,线程在后台运行,不会阻止主线程?

2 个答案:

答案 0 :(得分:0)

您正在使用future.get(9, TimeUnit.SECONDS);这将等待9秒,以便提交的线程完成。
如果您不需要主程序等待,也不需要线程返回任何内容,请使用executor.execute调用。
这是更新的代码......

    ExecutorService executor = null;
    try {
        executor = Executors.newFixedThreadPool(1);
        System.out.println("Start 1");
        Runnable task = new Runnable() {

            public void run() {

                System.out.println("Start 2");
                try {
                    Thread.sleep(7000);
                    System.out.println("Start 5");
                }
                catch (Exception e) {
                }
            }
        };
        System.out.println("Start 3");
        executor.execute(task);
        System.out.println("Start 4");
    }
    catch (Exception e) {
    }
    finally {
        System.out.println("finally");
        executor.shutdown();
    }
}

答案 1 :(得分:0)

在打印Start 4之前,您没有在当前代码中捕获超时异常,但是在“开始4”之后您正在捕获异常。线。因此,如果超时,您无法获得所需的输出。

更改您的代码

 Object result = future.get(9, TimeUnit.SECONDS);

   try {
      Object result = future.get(9, TimeUnit.SECONDS);
   } catch (CancellationException ce) {
       System.out.println("CancellationException ");
   } catch (ExecutionException ee) {
       System.out.println("ExecutionException ");
   } catch (InterruptedException ie) {
       System.out.println("InterruptedException ");
       Thread.currentThread().interrupt(); // ignore/reset
   }

使用上述代码,无论Start 4任务是否超时,您始终都会获得Future

有关详细信息,请参阅ThreadPoolExecutor文档页面中的afterExecute方法。

关于主线程的阻止,目前您正在get()上使用阻止Future来电。如果您不想阻止主线程,请将ExecutorService更改为ExecutorCompletionService,并根据上页的文档使用新API。