【JUC】实现多线程的第三种方式Callable
实现线程的三种方式比较
1. 继承Thread类
1 class ExtendsThread extends Thread{ 2 public void run(){ 3 System.out.println("Thread"); 4 } 5 } 6 public class RunnableDemo { 7 public static void main(String[] args) { 8 Thread thread = new Thread(new ExtendsThread()); 9 thread.start(); 10 } 11 }
2. 实现Runnable接口
1 class RunnableThread implements Runnable{ 2 @Override 3 public void run() { 4 System.out.println("Runnable"); 5 } 6 } 7 public class RunnableDemo { 8 public static void main(String[] args) { 9 Thread thread = new Thread(new RunnableThread()); 10 thread.start(); 11 } 12 }
3. 实现Callable接口(学习线程池的必要前提)
1 class CallableThread implements java.util.concurrent.Callable<Integer>{ 2 //带返回值 抛异常 3 @Override 4 public Integer call() throws Exception { 5 System.out.println("callable"); 6 return 2048; 7 } 8 } 9 public class CollableDemo { 10 public static void main(String[] args) throws ExecutionException, InterruptedException { 11 FutureTask<Integer> futureTask = new FutureTask<>(new CallableThread()); 12 Thread t1 = new Thread(futureTask,"CallableThread"); 13 t1.start(); 14 System.out.println(futureTask.get());//2048 15 } 16 }
Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutor或Scheduled-ThreadPoolExecutor执行。它们之间的区别是Runnable不会返回结果,而Callable可以返回结果。除了可以自己创建实现Callable接口的对象外,还可以使用工厂类Executors来把一个Runnable包装成一个Callable。
下面是Executors提供的,把一个Runnable包装成一个Callable的API。
public static Callable<Object> callable(Runnable task) // 假设返回对象Callable1
下面是Executors提供的,把一个Runnable和一个待返回的结果包装成一个Callable的API。
public static <T> Callable<T> callable(Runnable task, T result) // 假设返回对象Callable