1. 程式人生 > >每天一例多執行緒[day19]-----JDK實現Future的用法

每天一例多執行緒[day19]-----JDK實現Future的用法

  1. import java.util.concurrent.Callable;

  2. import java.util.concurrent.ExecutorService;

  3. import java.util.concurrent.Executors;

  4. import java.util.concurrent.Future;

  5. import java.util.concurrent.FutureTask;

  6. public class UseFuture implements Callable<String>{

  7. private String para;

  8. public UseFuture(String para){

  9. this.para = para;

  10. }

  11. /**

  12. * 這裡是真實的業務邏輯,其執行可能很慢

  13. */

  14. @Override

  15. public String call() throws Exception {

  16. //模擬執行耗時

  17. Thread.sleep(5000);

  18. String result = this.para + "處理完成";

  19. return result;

  20. }

  21. //主控制函式

  22. public static void main(String[] args) throws Exception {

  23. String queryStr = "query";

  24. //構造FutureTask,並且傳入需要真正進行業務邏輯處理的類,該類一定是實現了Callable介面的類

  25. FutureTask<String> future = new FutureTask<String>(new UseFuture(queryStr));

  26. FutureTask<String> future2 = new FutureTask<String>(new UseFuture(queryStr));

  27. //建立一個固定執行緒的執行緒池且執行緒數為1,

  28. ExecutorService executor = Executors.newFixedThreadPool(2);

  29. //這裡提交任務future,則開啟執行緒執行RealData的call()方法執行

  30. /**

  31. * 執行緒池中的submit和execute方法的區別:

  32. * 第一點是submit可以傳入實現Callable介面的例項物件

  33. * 第二點是submit方法有返回值

  34. */

  35. // f1.get() 如果執行完畢則返回null

  36. Future f1 = executor.submit(future);

  37. Future f2 = executor.submit(future2);

  38. System.out.println("請求完畢");

  39. try {

  40. //這裡可以做額外的資料操作,也就是主程式執行其他業務邏輯

  41. System.out.println("處理實際的業務邏輯...");

  42. Thread.sleep(1000);

  43. } catch (Exception e) {

  44. e.printStackTrace();

  45. }

  46. /**

  47. * future.get方法非同步等待獲取執行緒池的處理的最終結果

  48. * 如果call()方法沒有執行完成,則依然會進行等待

  49. *

  50. */

  51. System.out.println("資料:" + future.get());

  52. System.out.println("資料:" + future2.get());

  53. executor.shutdown();

  54. }

  55. }

列印:

  1. 請求完畢

  2. 處理實際的業務邏輯...

  3. 資料:query處理完成

  4. 資料:query處理完成

分析:我們在主函式中定義兩個FutureTask,並分別傳入實現了Callable介面的物件,定義一個固定數量執行緒池,將FutureTask物件submit進執行緒池,每個JDK實現的執行緒池都有execute和submit兩個方法,這兩個方法的區別:

1 submit可以傳入實現Callable介面的例項物件

2 submit方法有Future型別返回值(這個返回的Future物件有個get方法,可以返回執行緒池中提交的對應任務是否執行完畢,是則返回null)

我們可以通過定義的FutureTask例項物件的get方法去非同步獲取執行緒池中Callable物件的處理結果,如果call()沒有執行完畢,則會繼續等待。