1、透過執行緒池提交FutrueTask非同步任務
1 public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException { 2 3 long start = System.currentTimeMillis(); 4 ExecutorService executorService = Executors.newFixedThreadPool(3); 5 6 FutureTask<String> futureTask1 = new FutureTask<>(() -> { 7 TimeUnit.SECONDS.sleep(3); 8 return "futureTask1"; 9 }); 10 11 executorService.submit(futureTask1); 12 13 FutureTask<String> futureTask2 = new FutureTask<>(() -> { 14 TimeUnit.SECONDS.sleep(10); 15 return "futureTask2"; 16 }); 17 executorService.submit(futureTask2); 18 FutureTask<String> futureTask3 = new FutureTask<>(() -> { 19 TimeUnit.SECONDS.sleep(4); 20 return "futureTask3"; 21 }); 22 executorService.submit(futureTask3); 23 24 // 獲取結果才是等待執行緒執行完成,如果不獲取結果只是提交了任務 25 System.out.println(futureTask1.get()); 26 System.out.println(futureTask2.get()); 27 System.out.println(futureTask3.get()); 28 // FutrueTask介面一旦呼叫了get()方法,就會一直等待計算結果,容易造成執行緒阻塞 29 // get()方法一般放在程式後面 30 // 或者指定等待時間 31 System.out.println(futureTask2.get(3, TimeUnit.SECONDS)); // 會丟擲異常 32 33 executorService.shutdown(); 34 35 long end = System.currentTimeMillis(); 36 37 System.out.println(end - start); 38 }
2、輪詢獲取FutrueTask的處理結果
要想FutrueTask的任務儘量不阻塞其他執行緒任務,應該把get()放到後面,並且採用輪詢的方法獲取計算結果
1 public static void main(String[] args) { 2 ExecutorService executorService = Executors.newFixedThreadPool(3); 3 try { 4 FutureTask<String> futureTask = new FutureTask<>(() -> { 5 TimeUnit.SECONDS.sleep(5); 6 return "futureTask"; 7 }); 8 9 executorService.submit(futureTask); 10 11 System.out.println("執行其他任務..."); 12 13 // 輪詢耗費資源 14 while (true) { 15 if (futureTask.isDone()) { 16 System.out.println(futureTask.get()); 17 break; 18 } else { 19 TimeUnit.MILLISECONDS.sleep(500); 20 System.out.println("程式處理中,勿催"); 21 } 22 } 23 24 } catch (Exception e) { 25 e.printStackTrace(); 26 } finally { 27 executorService.shutdown(); 28 } 29 }