2010-03-10 120 views
0

我有需要做這樣的事情JVM不退出時發生TimeoutException異常

還有就是一些方法,每個類的列表代碼(可以說的execute())。我需要在每個類上調用該方法,並且每個調用都有一個固定的timeOut。現在,類的一個execute方法寫得很糟糕,並導致超時,因此jvm不會退出。我正在像這樣跑班。

java ExecutorServiceTest execute TestClass1 TestClass2 TestClass3 

爲什麼jvm在完成代碼執行後不能退出?

我得到以下輸出

In class 1 
In Class 2 
java.util.concurrent.TimeoutException 
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source) 
at java.util.concurrent.FutureTask.get(Unknown Source) 
at ExecutorServiceTest.main(ExecutorServiceTest.java:78) 
java.util.concurrent.TimeoutException 
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source) 
at java.util.concurrent.FutureTask.get(Unknown Source) 

第二類的執行超時,並在此之後,第三類的也執行超時。爲什麼第三類執行超時?

執行完成後,jvm不會退出。是什麼原因?另外爲什麼TestClass3執行超時?

import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 
import java.util.concurrent.TimeUnit; 
import java.util.concurrent.TimeoutException; 

class Task implements Callable<String> { 
    Object instance; 
    Method m; 
    Object[] input; 
    Task(Object instance, Method m, Object[] input) { 
     this.instance = instance; 
     this.m = m; 
     this.input = input; 
    } 
    public String call() { 
     String s = "initial"; 
     try { 
      m.invoke(instance, input); 
     } 
     catch (RuntimeException e) { 
     } 
     catch (Exception e) { 
     } 
     finally { 

     } 
     return s; 
    } 
} 


public class ExecutorServiceTest { 
    public static void main(String[] args) { 
     String methodName = args[0]; 
     String className; 
     List<Object> instanceList = new ArrayList<Object>(); 
     for (int i=1;i<args.length;i++) { 
      className = args[i]; 
      Object o = null; 
      try { 
       o = Class.forName(className).newInstance(); 
      } catch (InstantiationException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IllegalAccessException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (ClassNotFoundException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      instanceList.add(o); 
     } 
     ExecutorService executor = Executors.newSingleThreadExecutor(); 
     Iterator<Object> iter = instanceList.iterator(); 
     while (iter.hasNext()) { 
      Object o = iter.next(); 
      Method m = null; 
      try { 
       m = o.getClass().getDeclaredMethod(methodName, new Class[] {}); 
      } catch (SecurityException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (NoSuchMethodException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      Task t = new Task(o,m,new Object[]{}); 
      Future<String> fut = executor.submit(t); 
      try { 
       fut.get(2,TimeUnit.SECONDS); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (ExecutionException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (TimeoutException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
     executor.shutdown(); 
    } 
} 


public class TestClass1 { 
    public void execute() { 
     System.out.println("In class 1"); 
    } 
} 


public class TestClass2 { 
    public void execute() { 
     System.out.println("In class 2"); 
     boolean b = true; 
     while (b) { 

     } 
    } 
} 


public class TestClass3 { 
    public void execute() { 
     System.out.println("In class 3"); 
    } 
} 

回答

2

ExecutorService.shutdown()實際上並沒有停止所有正在運行執行人/線程,it just tells the service to stop accepting new tasks

void shutdown()
啓動先前提交的任務執行的有序關閉,但不會接受新任務。如果已經關閉,陽離子沒有其他影響。

您的TestClass2實例永遠不會停止運行,因爲它有一個永不停止的while(true)循環。

如果要立即停止ExecutorService,可以使用awaitTermination(long timeout, TimeUnit unit)shutdownNow()

+1

這兩個語句都不會停止JVM。 – 2010-03-10 19:44:56

+0

他們不應該。你看到有關TestInstance2的部分有無限循環嗎? – 2010-03-10 19:49:36

2

你需要調用executor.shutdown()或創建守護線程(使用適當的ThreadFactory傳遞給Executors.newSingleThreadExecutor()

+0

代碼中缺少executor.shutdown()語句。即使包含該聲明,它也不起作用。 – 2010-03-10 19:06:02