Callable<>和Runable相似,都是用於Java的併發執行。java
惟一的區別是,Runable的run方法的返回是void,而Callable的call方法是有返回值的。併發
call方法返回的類型是實現Callable<?>泛型接口時所指定的類型,否則會編譯出錯。ide
那麼,怎樣獲取call方法的返回值呢?——經過執行Callable,能夠返回的Future對象,經過調用future對象的get方法來獲取call方法的返回值。this
綜上,你把Callable當成是有返回值的Runable就好了,只不過Callable的是call,Runable的是run。spa
下面是演示代碼:線程
1 import java.util.ArrayList; 2 import java.util.concurrent.Callable; 3 import java.util.concurrent.ExecutionException; 4 import java.util.concurrent.ExecutorService; 5 import java.util.concurrent.Executors; 6 import java.util.concurrent.Future; 7 8 9 public class CallableTest{ 10 public static void main(String[] args) { 11 ExecutorService executorService= //建立線程池 12 Executors.newCachedThreadPool(); 13 ArrayList<Future<String>> list= 14 new ArrayList<Future<String>>(); 15 for (int i = 0; i < 10; i++) { 16 list.add(executorService //經過submit方法來提交Callable到線程池中執行 17 .submit(new TaskWithResult())); 18 } 19 for (Future<String> future : list) { 20 try { 21 System.out.println(future.get()); //經過get方法來獲取call返回值 22 } catch (InterruptedException e) { 23 e.printStackTrace(); 24 } catch (ExecutionException e) { 25 e.printStackTrace(); 26 } 27 } 28 } 29 30 31 static class TaskWithResult implements Callable<String>{ 32 private static int taskNum=0; 33 private int taskId=taskNum; 34 public TaskWithResult() { 35 taskNum++; 36 } 37 38 @Override 39 public String call() throws Exception { 40 try { 41 Thread.sleep(this.taskId*1000); //我製造的時間差,更直觀地顯示call和run方法的類似性。 42 } catch (InterruptedException e) { 43 e.printStackTrace(); 44 } 45 return "Result of TaskWithResult: "+this.taskId; 46 } 47 48 } 49 50 }
運行結果:code
Result of TaskWithResult: 0
Result of TaskWithResult: 1
Result of TaskWithResult: 2
Result of TaskWithResult: 3
Result of TaskWithResult: 4
Result of TaskWithResult: 5
Result of TaskWithResult: 6
Result of TaskWithResult: 7
Result of TaskWithResult: 8
Result of TaskWithResult: 9對象
以上的運行結果是每隔一秒打印一行的,這說明,call和run是差很少的。blog