今天,我們接著上篇文章,繼續來說我們的時時調度。前兩個例子我們調用的方法都是沒有傳回值得,可是實際應用中,一般的方法都是有傳回值得,我們這次來修改一下,看看有傳回值得方法如何做到時時調度。 一、時時調度變形 1、控制類
public class timeTest { /** * 時時調度 * 3秒後開始,每隔1秒列印一次 */ public static String executePerDay() { // 建立一個可重用固定線程數的線程池,以共用的無界隊列方式來運行這些線程。 ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); System.out.println("時時調度"); System.out.println("getTest()"+ new Date().toString()); Future future =executor.schedule( new returnTest(), //調用執行方法的類 3000, //延遲3秒後執行 TimeUnit.MILLISECONDS); String result=""; try { //取出返回結果 result = future.get().toString(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } }
2、真正執行者
public class returnTest implements Callable<String> { @Override public String call() throws Exception { //調用實際執行的方法 return getNowTime(); } private String getNowTime(){ //列印測試時間 String result="getTest()"+ new Date().toString(); System.out.println(result); return result; }}
3、主類
public class mainTest { public static void main(String[] args) { timeTest test = new timeTest(); //時時調度 String result=test.executePerDay(); System.out.println("收到--"+result); }}
二、分析
1、Executors(線程池)
從JAVA5開始新增了一個Executors工具類來產生線程池,它有如下幾個靜態Factory 方法來建立線程池。
public static ExecutorService newFixedThreadPool(int nThreads)
建立一個可重用固定線程數的線程池,以共用的無界隊列方式來運行這些線程。
在任意點,在大多數 nThreads 線程會處於處理任務的活動狀態。如果在所有線程處於活動狀態時提交附加任務,
則在有可用線程之前,附加任務將在隊列中等待。如果在關閉前的執行期間由於失敗而導致任何線程終止,那麼一個新線程將代替它執行後續的任務(如果需要)。在某個線程被顯式地關閉之前,池中的線程將一直存在。
public static ExecutorService newSingleThreadExecutor()
建立一個使用單個 worker 線程的 Executor,以無界隊列方式來運行該線程。(注意,如果因為在關閉前的執行期間出現失敗而終止了此單個線程,那麼如果需要,一個新線程將代替它執行後續的任務)。
可保證順序地執行各個任務,並且在任意給定的時間不會有多個線程是活動的。與其他等效的newFixedThreadPool(1)不同,可保證不能對ThreadPoolExecutor重新進行配置來使用更多的線程。
注意:newSingleThreadExecutor與newFixedThreadPool(1)不同之出在於:
newSingleThreadExecutor返回的ExcutorService在解構函式finalize()會調用shutdown(),即如果我們沒有對它調用shutdown(),那麼可以確保它在被回收時調用shutdown()來終止線程。 2、ScheduledExecutorService(任務調度)
在ExecutorService的基礎上,ScheduledExecutorService提供了按時間安排執行任務的功能,它提供的方法主要有:
schedule(task,initDelay):安排所提交的Callable或Runnable任務在initDelay指定的時間後執行。//可以用來順延強制有傳回值的任務
scheduleAtFixedRate():安排所提交的Runnable任務按指定的間隔重複執行。//可以用來執行循環性任務
scheduleWithFixedDelay():安排所提交的Runnable任務在每次執行完後,等待delay所指定的時間後重複執行。//可以用來執行循環性定時任務
3、Future(接受返回參數)
Future表示非同步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,並擷取計算的結果。
計算完成後只能使用 get 方法來擷取結果,如有必要,計算完成前可以阻塞此方法。取消則由 cancel 方法來執行。還提供了其他方法,以確定任務是正常完成還是被取消了。一旦計算完成,就不能再取消計算。 總結:
關於時時調度,我們現在可以時時或定時調用任意的方法,但是有一個問題,那就是在調用有傳回值得方法時,我們只能延遲調用,卻不能周期性的調用。對於這點,我們會在以後的學習過程中,採用其他方式解決。