Callable 和 Runnable 异同
Callable 和 Runnable 都可以作为任务去执行,异同点主要表现在以下几点
- 1.Callable是一个接口需要实现call()方法,Runnable也是一个接口需要是实现run() 方法
- 2.call()方法可以抛出异常,run()方法无法抛出异常,只能自行处理
- 3.Callable类有泛型,在创建的时候可以传递进去,在实现call()方法的时候可以返回
- 4.Callable执行任务的时候可以通过FutureTask知晓任务执行的状态以及结果(FutureTask的get()方法),Runnable无法知晓任务执行的状态以及结果.
- 5.Runnable实例对象需要Thread包装启动,Callable实例对象需要先通过FutureTask包装再丢给Thread包装执行(FutrueTask对象本质还是Runnable),当然在线程池里不需要那么复杂.
测试代码如下
1 package learn.thread; 2 3 import java.util.concurrent.Callable; 4 import java.util.concurrent.FutureTask; 5 6 public class CallableAndRunnable { 7 8 public static void main(String[] args) { 9 testCallable(); 10 testRunnable(); 11 } 12 13 /** 14 * 测试runnable 15 */ 16 private static void testRunnable() { 17 //创建执行对象 18 Runnable r = new Runnable() { 19 @Override 20 public void run() { 21 System.out.println("当前线程名称是:" + Thread.currentThread().getName()); 22 try { 23 Thread.sleep(2000L); 24 } catch (InterruptedException e) { 25 e.printStackTrace(); 26 } 27 System.out.println("runnable 执行完毕"); 28 } 29 }; 30 //包装对象 31 Thread t = new Thread(r); 32 //启动线程执行 33 t.start(); 34 } 35 36 /** 37 * 测试callable 38 */ 39 private static void testCallable() { 40 //创建执行对象 41 Callable<Result> ca = new Callable<Result>() { 42 @Override 43 public Result call() throws Exception { 44 System.out.println("当前线程名称是:" + Thread.currentThread().getName()); 45 Thread.sleep(2000L); 46 return new Result("callable 执行完毕"); 47 } 48 }; 49 //包装对象 50 FutureTask<Result> ft = new FutureTask<Result>(ca); 51 try { 52 //启动线程执行 53 new Thread(ft).start(); 54 //获取结果 55 System.out.println(ft.get().getMsg()); 56 } catch (Exception e) { 57 e.printStackTrace(); 58 } 59 } 60 61 /** 62 * 返回实体 63 */ 64 static class Result { 65 private String msg; 66 67 public Result() { 68 super(); 69 } 70 71 public Result(String msg) { 72 super(); 73 this.msg = msg; 74 } 75 76 public String getMsg() { 77 return msg; 78 } 79 80 public void setMsg(String msg) { 81 this.msg = msg; 82 } 83 } 84 85 }