03 创建线程的第3式
实现Callable<T>接口 :有泛型 实现call方法 有返回值 可以抛出异常
1 定义一个类实现Callable接口 可以指定泛型
2 实现call方法 有返回值 返回值类型是指定的泛型类型
3 使用Executors工厂获取ExecutorService线程池
4 将Callable子类实例交给ExecutorService的submit方法 并获取Future对象
5 调用Future对象get方法 获取线程执行结果
6 ExecutorService调用shutdown方法关闭线程池
案例:
public class MyCallable implements Callable<Integer> { private int number; public MyCallable(int number) { this.number = number; } public Integer call() throws Exception { int sum = 0; for (int x = 1; x <= number; x++) { sum += x; } return sum; } } public class CallableDemo { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService pool = Executors.newFixedThreadPool(2); Future<Integer> f1 = pool.submit(new MyCallable(100)); Future<Integer> f2 = pool.submit(new MyCallable(200)); Integer i1 = f1.get(); Integer i2 = f2.get(); System.out.println(i1); System.out.println(i2); pool.shutdown(); } }
关于ExecutorService的知识在后面线程池中讲述
Callable 与 Runnabel
Callable中的任务方法是call
call方法可以有返回值 返回值类型通过在类上指定泛型参数来确定
cal方法可以抛出异常l
他的启动方式必须借助ExecutorService线程池的submit方法
通过Future的get方法获取执行结果
Runnable的任务方法是run 他没有返回值 也不能抛出异常
Runnable启动线程的方法通常为start
案例2:求和案例
1 public class MyCallable implements Callable<Integer> { 2 3 private int number; 4 5 public MyCallable(int number) { 6 this.number = number; 7 } 8 9 @Override 10 public Integer call() throws Exception { 11 int sum = 0; 12 for (int x = 1; x <= number; x++) { 13 sum += x; 14 } 15 return sum; 16 } 17 } 18 19 public class CallableDemo { 20 public static void main(String[] args) throws InterruptedException, ExecutionException { 21 // 创建线程池对象 22 ExecutorService pool = Executors.newFixedThreadPool(2); 23 24 // 可以执行Runnable对象或者Callable对象代表的线程 25 Future<Integer> f1 = pool.submit(new MyCallable(100)); 26 Future<Integer> f2 = pool.submit(new MyCallable(200)); 27 28 // V get() 29 Integer i1 = f1.get(); 30 Integer i2 = f2.get(); 31 32 System.out.println(i1); 33 System.out.println(i2); 34 35 // 结束 36 pool.shutdown(); 37 } 38 }
不积跬步无以至千里