1. 程式人生 > >【Java併發核心五】Future 和 Callable

【Java併發核心五】Future 和 Callable

預設情況下,執行緒Thread物件不具有返回值的功能,如果在需要取得返回值的情況下會極為不方便。jdk1.5中可以使用Future 和 Callable 來獲取執行緒返回值

Callable 可以 看成與 Runnable 一樣的但是有返回值的介面。

Callable介面的call()方法有返回值,而Runnable介面的run方法沒有返回值;

Callable介面的call()方法可以宣告丟擲異常,而Runnable介面的run方法不可以宣告丟擲異常。

執行完Callable介面中的任務後,返回值是通過Future介面進行獲取的。

看例子:

     final SimpleDateFormat sf = new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); ExecutorService executorService = Executors.newCachedThreadPool(); // ExecutorService executorService = Executors.newFixedThreadPool(3); List<Future<String>> futureList = new ArrayList<Future<String>>();
// 此執行緒池執行5個執行緒 for (int i = 0; i < 5; i++) { final int index = i; // 使用 submit 方法 和 execute 方法的區別是,execute 方法沒有返回值,而 submit 方法有返回值。 Future<String> future = executorService.submit(new Callable<String>() { @Override
public String call() throws Exception { System.out.println("Thread-" + index + "-begin-" + sf.format(new Date())); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread-" + index + "-end-" + sf.format(new Date())); return "index-" + index; } }); futureList.add(future); } // future.get() 是阻塞執行的,所以獲取值要線上程都啟動之後,再獲取 for (Future<String> future : futureList) { try { System.out.println(future.get()); // 獲取執行緒返回值 } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }

ExecutorService 的 submit 方法 和 execute 方法的區別是,

  execute 方法沒有返回值,不能直接捕獲異常,但可以通過自定義ThreadFactory的方式捕獲異常;

  submit 方法有返回值,可以直接使用 catch Execution-Exception捕獲異常。

Future 的常用api:

get()    獲取執行緒返回值,阻塞執行

get(long timeout, TimeUnit unit)    獲取執行緒返回值(有超時時間),阻塞執行 cancel(boolean mayInterruptIfRunning)    取消執行,入參為true表示,如果執行緒正在執行則中斷執行;為false表示,如果執行緒沒有在執行才中斷繼續執行;返回值表示取消執行命令是否成功完成 isCancelled()    是否已取消執行 isDone()    如果完成此任務,則返回true。完成可能是由於正常終止、異常或取消——在所有這些情況下,此方法將返回true。