在前面我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。 如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。 而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。 今天我们就来讨论一下Callable、Future和FutureTask三个类的使用方法。以下是本文的目录大纲: 一.Callable与Runnable 二.Future 三.FutureTask
工具/原料
方法/步骤
1创建一个实现callable的实现类具体代码如下所示:import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException; /** * 创建线程的方式三:实现callable接口 --》jdk5.0新增 */ // 1、创建一个实现callable的实现类public class NumThread implements Callable { private int length; public void setLength(int length) { this.length = length; } // 2、实现call方法,将此线程需要执行的操作声明在call方法中 public Integer call() throws Exception { int sum = 0; for (int i = 0; i <= length; i++) { if (i % 2 == 0) { sum += i; System.out.println(i); } } return sum; }}
2编写测试类代码如下所示:import java.util.concurrent.FutureTask;public class ThreadNew { public static void main(String[] args) { // 3、创建callable实现类的对象 NumThread numThread = new NumThread(); // 3.1 传参数 numThread.setLength(100); // 4、将此callable实现类的对象作为参数传递到FutureTask的构造器中,创建FutureTask对象 FutureTask integerFutureTask = new FutureTask( numThread); // 5、将FutureTask作为参数传递Thread构造器中,创建Thread对象,并调用start方法 new Thread(integerFutureTask).start(); try { // 6、获取Callable中call方法中的返回值 // get()返回值即为futureTask构造器参数Callable实现类重写的call的返回值 Integer sum = integerFutureTask.get(); System.out.println('总计:' + sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}
3代码详解:1、相较于Thread和Runable实现多线程的方式其可以获取线程执行的返回值2、在NumThread 中的以下代码是根据set方法方式向callable实现类中传参数,然后再call方法中使用。private int length; public void setLength(int length) {this.length = length;}
5总结:如何理解实现callable接口的方式创建多线程比实现Runable接口创建线程的方式强大? 1、call() 可以返回任意值 2、call() 可以抛出异常,被外面的操作捕获,获取异常的信息 3、Callable是支持泛型的
注意事项
jdk 1.8 intellij IDEA 2018