Runnable和Callable有什么区别?
主要区别
- 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 面试题汇总小程序浏览,扫二维码
所有资源资源汇总于公众号