创建线程有两种方式:继承Thread
和实现Runnable
接口
但是都有一个共同的缺陷:
执行完任务后,无法获取执行结果
通过Callable
和Future
可以得到任务执行完之后的结果
-
Callable
与Runnable
接口对比
Callable
是泛型的接口,其中有一个call
函数,call
函数的返回类型就是创建Callable
时传进去的类型
-
Future
也是以个接口, 对于任务可以进行取消, 查询是否执行完成等, 可以监视目标线程调用call
的情况
package io.haitaoc.concurrency.example.aqs;
import java.util.concurrent.*;
public class FutureExample {
// 返回类型是String
static class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("do something in callable");
Thread.sleep(5000);
return "Done";
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newCachedThreadPool();
// 通过Future接收另外一个线程计算的结果
Future<String> future = executorService.submit(new MyCallable());
System.out.println("do something in main");
Thread.sleep(1000);
String result = future.get();
System.out.println(result);
}
}
-
FutureTask
父类是RunnableFuture
, 执行Callable
类型的任务,并且有Future
的特性
package io.haitaoc.concurrency.example.aqs;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureTaskExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<String> futureTask = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("do something in callable");
Thread.sleep(5000);
return "Done";
}
});
// 启动任务
new Thread(futureTask).start();
System.out.println("do something in main");
Thread.sleep(1000);
String result = futureTask.get();
System.out.println(result);
}
}
网友评论