2015-05-19 92 views
2

之前完全執行的線程當我運行此:的ThreadPoolExecutor不關閉

import java.util.concurrent.*; 

public class Foo { 

    static public ExecutorService pool = 
      new ThreadPoolExecutor(
        50, 200, 15, TimeUnit.SECONDS, 
        new LinkedBlockingQueue<>(), 
        ExLogThread.factory); 

    public static void main(String args[]) { 
     try { 
      pool.execute(Foo::startApp); 
      pool.shutdown(); 
      System.exit(0); 
     } catch (Exception ex) { 
      for (StackTraceElement elem : ex.getStackTrace()) 
       System.out.println(elem); 
      System.exit(-1); 
     } 
    } 

    static void startApp() { 
     throw new RuntimeException(); 
    } 

} 

final class ExLogThread extends Thread { 

    public static final ThreadFactory factory = 
      ExLogThreadFactory.instance; 
    private final StackTraceElement[] predecessor; 
    private final Runnable r; 

    public ExLogThread(Runnable r) { 
     super(); 
     predecessor = Thread.currentThread().getStackTrace(); 
     this.r = r; 
    } 

    @Override 
    public void run() { 
     try { 
      r.run(); 
     } catch (Exception ex) { 
      log(ex, predecessor); 
      System.exit(-1); 
     } 
    } 

    private static class ExLogThreadFactory 
      implements ThreadFactory { 

     static public ExLogThreadFactory instance = 
       new ExLogThreadFactory(); 

     @Override 
     public Thread newThread(Runnable r) { 
      return new ExLogThread(r); 
     } 

     private ExLogThreadFactory() {} 

    } 

    private static void log(Exception ex, StackTraceElement[] predecessor) { 
     // for example's sake 
     for (StackTraceElement elem : ex.getStackTrace()) 
      System.out.println(elem); 
     for (int i = 1; i < predecessor.length; i++) 
      System.out.println(predecessor[i]); 
    } 

} 

它與0的代碼怎麼回事退出?我認爲ThreadPoolExexcutor等待排隊的任務在關閉之前運行。如果是的話,這應該以-1的代碼退出。

如果我沒有委託線程工廠創建線程的子類的創作,我得到一個錯誤的主線程退出時的0

代碼我猜我得到的東西之前通知創建Thread的子類時出錯,但我不知道在哪裏。幫助將不勝感激。

回答

2

呼叫pool#awaitTermination後調用pool#shutdown

shutdown's javadoc

這種方法不會等待以前提交的任務完成 執行。使用awaitTermination來做到這一點。

1

您致電System.exit(0)將終止正在運行的ExecutorService

shutdown()的呼叫是非阻塞的;它只是表示執行者服務不會提交更多任務,因此可以將已完成的任務作爲資源進行清理。因爲它不會阻止,所以立即調用System.exit(0),放棄提交的任務。

如果您希望線程等待提交到ExecutorService的所有任務都已完成,請致電awaitTermination(),指出您願意等待多久。