主要區別
- Runnable 接口 run 方法無返回值;Callable 接口 call 方法有返回值,支持泛型
- Runnable 接口 run 方法只能拋出運行時異常,且無法捕獲處理;Callable 接口 call 方法允許拋出異常,可以獲取異常信息
測試代碼
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class TestRunnableAndCallable { public static void main(String[] args) { testImplementsRunable(); testImplementsCallable(); testImplementsCallableWithException(); } //測試實現Runnable接口的方式創建、啟動線程 public static void testImplementsRunable() { Thread t1 = new Thread(new CustomRunnable()); t1.setName("CustomRunnable"); t1.start(); } //測試實現Callable接口的方式創建、啟動線程 public static void testImplementsCallable() { Callable<String> callable = new CustomCallable(); FutureTask<String> futureTask = new FutureTask<String>(callable); Thread t2 = new Thread(futureTask); t2.setName("CustomCallable"); t2.start(); try { System.out.println(futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } //測試實現Callable接口的方式創建、啟動線程,拋出異常 public static void testImplementsCallableWithException() { Callable<String> callable = new CustomCallable2(); FutureTask<String> futureTask = new FutureTask<String>(callable); Thread t3 = new Thread(futureTask); t3.setName("CustomCallableWithException"); t3.start(); try { System.out.println(futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } //實現Runnable接口,重寫run方法 class CustomRunnable implements Runnable { public void run() { System.out.println(Thread.currentThread().getName()); // throw new RuntimeException("aaa"); } } //實現Callable接口,重寫call方法 class CustomCallable implements Callable<String> { public String call() throws Exception { System.out.println(Thread.currentThread().getName()); return "Callable Result"; } } //實現Callable接口,重寫call方法無法計算拋出異常 class CustomCallable2 implements Callable<String> { public String call() throws Exception { System.out.println(Thread.currentThread().getName()); throw new Exception("I can compute a result"); } }
打印結果
CustomRunnable
CustomCallable
Callable Result
CustomCallableWithException
java.util.concurrent.ExecutionException: java.lang.Exception: I can compute a result
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at constxiong.interview.TestRunnableAndCallable.testImplementsCallableWithException(TestRunnableAndCallable.java:46)
at constxiong.interview.TestRunnableAndCallable.main(TestRunnableAndCallable.java:12)
Caused by: java.lang.Exception: I can compute a result
at constxiong.interview.CustomCallable2.call(TestRunnableAndCallable.java:81)
at constxiong.interview.CustomCallable2.call(TestRunnableAndCallable.java:1)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:748)
- Java 自學指南
- Java 面試題匯總PC端瀏覽【點這里】
- Java知識圖譜
- Java 面試題匯總小程序瀏覽,掃二維碼
所有資源資源匯總於公眾號