1 package day2_6; 2 3 import java.util.concurrent.Callable; 4 import java.util.concurrent.ExecutionException; 5 import java.util.concurrent.FutureTask; 6 7 /** 8 * 创建线程的方式三:实现Callable接口。 ---JDK5.0新增 9 * 10 * 如何理解实现Callable接口的方式创建多线程,比实现Runable接口创建多线程方式更强大? 11 * 1.call()可以有返回值 12 * 2.call()可以抛出异常,被外面的操作捕获,获取异常的信息 13 * 3.Callable是支持泛型的 14 * 15 * 16 * @Author Tianhao 17 * @create 2021-02-06-11:17 18 */ 19 20 //1.创建一个Callable接口的实现类 21 class NumThread implements Callable<Integer> { 22 //2.实现Callable接口的抽象方法call(),将线程需要执行的操作声明在此方法中 23 //call()可以返回值,如果不需要返回值,就return null 24 @Override 25 public Integer call() throws Exception { 26 int sum = 0; 27 for (int i = 1; i <= 100; i++) { 28 // Thread.sleep(1000); 29 if (i%2 ==0) { 30 System.out.println(Thread.currentThread().getName() + "打印:" + i); 31 sum += i; 32 } 33 } 34 return sum; 35 } 36 } 37 38 public class ThreadNew { 39 public static void main(String[] args) { 40 //3.创建Callable实现类对象 41 NumThread numThread = new NumThread(); 42 //4.将此Callable实现类对象作为参数传递到FutureTask类的构造器, 43 // 并创建FutureTask对象 44 FutureTask<Integer> futureTask = new FutureTask<>(numThread); 45 //5.创建线程对象 46 //因为FutureTask间接实现了Runnable接口, 47 // 所以其对象可以作为参数传递到Thread类的构造器中,并创建线程对象 48 Thread t = new Thread(futureTask); 49 t.setName("数字线程"); 50 //6.启动线程 51 //仍然是调用Thread对象的start方法来启动线程, 52 // 底层实际调用的是Callable实现类的实现方法call() 53 t.start(); 54 55 try { 56 //7.获取线程返回值(根据业务需要可选) 57 //因为FuntureTask间接实现了Future接口, 58 //所以可以通过get()获取其构造器参数Callable实现类的call()返回值 59 Integer result = futureTask.get(); 60 Thread.currentThread().setName("主线程"); 61 System.out.println(Thread.currentThread().getName() + "打印总和:" + result); 62 } catch (InterruptedException e) { 63 e.printStackTrace(); 64 } catch (ExecutionException e) { 65 e.printStackTrace(); 66 } 67 } 68 }