來自:http://www.cnblogs.com/taven/archive/2011/12/17/2291469.html
1 import java.util.concurrent.Callable; 2 3 import java.util.concurrent.ExecutionException; 4 5 import java.util.concurrent.ExecutorService; 6 7 import java.util.concurrent.Executors; 8 9 import java.util.concurrent.Future; 10 11 import java.util.concurrent.ScheduledExecutorService; 12 13 import java.util.concurrent.TimeUnit; 14 15 16 17 /** 18 19 在J2SE之前啟動一個任務是通過調用Thread類的start方法來實現的,任務的提交和執行是同時進行的,如果想對任務的執行進行調度,或是控制同時執行的線程數量就需要額外的編寫代碼來完成. 20 21 J2SE5.0提供了一個新的任務執行架構,可以輕松地高度和控制任務的執行,並且可以建立一個線程池來執行任務. 22 23 實例介紹如何使用新的任務執行架構,運行Runnable和Callable任務,包括定時執行任務,按規律執行任務和停止任務. 24 25 關鍵技術剖析: 26 27 使用新的任務執行框架的關鍵技術如下: 28 29 1.Executor服務對象是用來執行Runnable任務的,常用的方法如下: 30 31 execute方法用於執行Runnable類型的任務. 32 33 2.ExecutorService服務對象能執行和終止Callable任務,它繼承了Executor,所以也能執行Runnable任務.常用的方法如下 34 35 a) submit方法用來提交Callable或Runnable任務,並返回代表此任務的Future對象. 36 37 b) invokeAll方法批處理任務集合,並返回一個代表這些任務的Future對象集合 38 39 c) shutdown方法在完成自己已提交的任務后關閉服務,不再接受新任務. 40 41 d) shutdownNow方法停止所有正在執行的任務並關閉服務. 42 43 e) isTerminated測試是否所有任務都執行完畢了 44 45 g) isShutdown測試是否該ExecutorService已被關閉 46 47 3.ScheduledExecutorService服務對象繼承ExecutorService,提供了按時間安排執行任務的功能.常用的方法如下: 48 49 a)schedule(task,initDelay)方法安排所提交的Callable或Runnable任務在initDelay指定的時間后執行. 50 51 b)scheduleAtFixedRate方法安排所提交的Runnable任務按指定的間隔重復執行. 52 53 c)scheduleWithFixedDelay方法安排所提交的Runnable任務在每次執行完后,等待delay所指定的時間后重復執行. 54 55 4.Executors類用來創建各種服務對象,常用的方法如下: 56 57 a)callable(Runnable task)方法將Runnable的任務轉化成Callable的任務. 58 59 b)newSingleThreadExecutor方法產生一個ExecutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整,線程執行完任務后返回線程池,供執行下一次任務使用. 60 61 c)newCachedThreadPool方法會產生一個ExecutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整,線程執行完任務后返回線程池,供執行下一次任務使用. 62 63 d)newFixedThreadPool(int poolSize)方法產生一個ExecutorService對象,這個對象帶有一個大小為poolSize的線程池,若任務數量大於poolSize,任務會被放在一個隊列里順序執行. 64 65 e)newSingleThreadScheduledExecutor方法產生一個ScheduledExecutorService對象,這個對象的線程池大小為1,若任務多於一個,任務將按先后順序執行. 66 67 f)newScheduledThreadPool(int poolSize)方法產生一個ScheduledExecutorService對象,這個對象的線程池大小為poolSize,若任務數量大於poolSize,任務會在一個隊列里等待執行. 68 69 */ 70 71 public class ExecuteArch { 72 73 /**該線程輸出一行字符串*/ 74 75 public static class MyThread implements Runnable{ 76 77 public void run(){ 78 79 System.out.println("Task repeating. " + System.currentTimeMillis()); 80 81 try{ 82 83 Thread.sleep(1000); 84 85 }catch(InterruptedException e){ 86 87 System.out.println("Task interrupted. " + System.currentTimeMillis()); 88 89 } 90 91 } 92 93 } 94 95 /**該Callable結束另一個任務*/ 96 97 public static class MyCallable implements Callable{ 98 99 private Future future; 100 101 public MyCallable(Future future){ 102 103 this.future = future; 104 105 } 106 107 public String call(){ 108 109 System.out.println("To cancell Task..." + System.currentTimeMillis()); 110 111 this.future.cancel(true); 112 113 return "Task cancelled!"; 114 115 } 116 117 } 118 119 120 121 public static void main(String... args)throwsInterruptedException,ExecutionException{ 122 123 //產生一個ExcutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整 124 125 //線程執行完任務后返回線程池,供執行下一次任務使用 126 127 ExecutorService cachedService = Executors.newCachedThreadPool(); 128 129 Future myThreadFuture = cachedService.submit(new MyThread()); 130 131 Future myCallableFuture = cachedService.submit(newMyCallable(myThreadFuture)); 132 133 System.out.println(myCallableFuture.get()); 134 135 System.out.println("--------------------"); 136 137 138 139 //將Runnable任務轉換成 Callable任務 140 141 Callable myThreadCallable = Executors.callable(new MyThread()); 142 143 Future myThreadCallableFuture = cachedService.submit(myThreadCallable); 144 145 //對於Runnable任務,轉換成Callable任務后,也沒有返回值 146 147 System.out.println(myThreadCallableFuture.get()); 148 149 cachedService.shutdownNow(); 150 151 System.out.println("--------------------"); 152 153 154 155 //產生一個ExecutorService對象,這個對象帶有一個大小為poolSize的線程池 156 157 //若任務大於poolSize,任務會被放在一個queue里順序執行 158 159 ExecutorService fixedService = Executors.newFixedThreadPool(2); 160 161 fixedService.submit(new MyThread()); 162 163 fixedService.submit(new MyThread()); 164 165 //由於線程池大小為2,所以后面的任務必須等待前面的任務執行完畢后才能被執行 166 167 myThreadFuture = fixedService.submit(new MyThread()); 168 169 myThreadFuture = fixedService.submit(new MyCallable(myThreadFuture)); 170 171 System.out.println(myCallableFuture.get()); 172 173 fixedService.shutdown(); 174 175 System.out.println("--------------------"); 176 177 178 179 //產生一個ScheduleExecutorService對象,這個對象的線程池大小為poolSize 180 181 //若任務數量大於poolSize,任務會在一個queue里等待執行 182 183 ScheduledExecutorService fixedScheduledService = Executors.newScheduledThreadPool(2); 184 185 MyThread task1 = new MyThread(); 186 187 //使用任務執行服務立即執行任務1,而且此后每隔2秒執行一次任務1 188 189 myThreadFuture = fixedScheduledService.scheduleAtFixedRate(task1, 0, 2, TimeUnit.SECONDS); 190 191 MyCallable task2 = new MyCallable(myThreadFuture); 192 193 //使用任務執行服務等待5秒后執行任務2,執行它后將任務1關閉. 194 195 myCallableFuture = fixedScheduledService.schedule(task2,5,TimeUnit.SECONDS); 196 197 System.out.println(myCallableFuture.get()); 198 199 fixedScheduledService.shutdownNow(); 200 201 } 202 203 }