一般情况下,我们执行并发任务时都是用Thread和Runnable,或者线程池,但是这些方法都不能返回执行的结果,需要通过Handler发送消息的方法,返回我们需要的结果。其实,java提供了java.util.concurrent包下提供了一个可执行并发任务的接口Callable。
下面我们看看Callable的基本使用。
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "name: " + name + " age: " + age;
}
}
/**
* 自定义Callable类
* 注意Callable的泛型类型就是call()方法返回值的类型
*/
class MyCallable implements Callable<Student> {
private String name;
private int age;
public MyCallable(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Student call() throws Exception {
//线程返回值
return new Student(name, age);
}
}
public class ThreadTest2 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
//用List集合存储线程返回的数据
List<Future<Student>> result = new ArrayList<>();
for (int i = 0; i < 10; i++) {
//submit的返回值是Future<T>类型
result.add(executorService.submit(new MyCallable("XiaoHong" + i, 20 + i)));
}
for (int i = 0; i < result.size(); i++) {
Future<Student> studentFuture = result.get(i);
try {
//获取每一个任务的返回值
Student student = studentFuture.get();
PrintUtils.print(student.toString());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
/**
* 输出:
*
* name: XiaoHong0 age: 20
* name: XiaoHong1 age: 21
* name: XiaoHong2 age: 22
* name: XiaoHong3 age: 23
* name: XiaoHong4 age: 24
* name: XiaoHong5 age: 25
* name: XiaoHong6 age: 26
* name: XiaoHong7 age: 27
* name: XiaoHong8 age: 28
* name: XiaoHong9 age: 29
*
*/
}
}
从输出结果可以看出确实返回了线程的执行结果
值得注意的是Callable接口是一个带泛型的接口,泛型的类型就是call()方法返回的数据类型,也是我们希望线程返回的数据类型。
Callable的执行结果是保存在Future<T>对象中的。主要是线程池的submit方法返回的是Future<T>类型的数据,其中T就是Callable的泛型类型,也是我们希望返回的数据类型。
另外,我们是通过Future对象的get方法获取任务的返回数据的。
网友评论