ScheduledExecutorService建立newScheduledThreadPool執行緒池遇到的問題
package test; import java.util.Date; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; public class Test { static class EchoServer1 implements Runnable { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(10000); i++; } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(i==3){ throw new java.lang.RuntimeException("Dasds"); } System.out.println(i+"-"+10+"-"+Thread.currentThread().getName() +"-"+new Date()); } } static int i =0; static class EchoServer2 implements Runnable { @Override public void run() { // TODO Auto-generated method stub System.out.println(20+"-"+Thread.currentThread().getName() +"-"+new Date()); } } public static void main(String[] args){ ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); executor.scheduleAtFixedRate( new EchoServer2(), 0, 10, TimeUnit.SECONDS); ScheduledFuture<?> future = executor.scheduleAtFixedRate( new EchoServer1(), 0, 5, TimeUnit.SECONDS); try { try { future.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ExecutionException e) { Throwable cause = e.getCause(); cause.printStackTrace(); future.cancel(false); } } }
1、可用scheduledFuture 捕獲 task異常,並停止某個task,不影響其餘task的執行。
2、若task執行時間大於間隔時間,則下一次task將在上一次task後馬上執行,不會產生同時2個相同task的執行情況發生。
3、若執行緒池大小小於task大小,則若在情況2下,有另一條task佔據了現有執行緒池(即阻塞了原task的一次執行),
則會造成 原task在另一條task結束後,執行兩次。
執行緒池為1:
20-pool-1-thread-1-Mon Dec 29 21:34:08 CST 2014
1-10-pool-1-thread-1-Mon Dec 29 21:34:18 CST 2014
2-10-pool-1-thread-1-Mon Dec 29 21:34:28 CST 2014
20-pool-1-thread-1-Mon Dec 29 21:34:28 CST 2014
20-pool-1-thread-1-Mon Dec 29 21:34:38 CST 2014
20-pool-1-thread-1-Mon Dec 29 21:34:38 CST 2014
java.lang.RuntimeException: Dasds
at test.Test$EchoServer1.run(Test.java:23)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
20-pool-1-thread-1-Mon Dec 29 21:34:48 CST 2014
執行緒池為2:
20-pool-1-thread-1-Mon Dec 29 21:33:13 CST 2014
20-pool-1-thread-1-Mon Dec 29 21:33:23 CST 2014
1-10-pool-1-thread-2-Mon Dec 29 21:33:23 CST 2014
20-pool-1-thread-1-Mon Dec 29 21:33:33 CST 2014
2-10-pool-1-thread-2-Mon Dec 29 21:33:33 CST 2014
20-pool-1-thread-1-Mon Dec 29 21:33:43 CST 2014
java.lang.RuntimeException: Dasds
at test.Test$EchoServer1.run(Test.java:23)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
20-pool-1-thread-2-Mon Dec 29 21:33:53 CST 2014