Callable是类似于Runnable的接口,实现Callable的类和实现Runnable的类都是可被其他线程执行的任务。
优点:有返回值
缺点:实现繁琐
简单实现:
CallableAndFuture.java
/**
* 简单实现
*
* @author :liuqi
* @date :2018-06-13 11:10.
*/
public class CallableAndFuture {
static class MyThread implements Callable<String> {
@Override
public String call() throws Exception {
return "Hello world";
}
} public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
Future<String> future = threadPool.submit(new MyThread());
try {
System.out.println(future.get());
} catch (Exception e) { } finally {
threadPool.shutdown();
}
}
}
运行结果:
Hello world
进阶:
Race.java
/**
* 实现callable类
*
* @author :liuqi
* @date :2018-06-13 10:13.
*/
public class Race implements Callable<Integer> {
private String name;
private long time;
private boolean flag = true;
// 步数
private int step = 0;
public Race(){
}
public Race(String name,int time){
super();
this.name = name;
this.time = time;
}
@Override
public Integer call() throws Exception {
while(flag){
Thread.sleep(time);
step++;
}
return step;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public long getTime() {
return time;
} public void setTime(long time) {
this.time = time;
} public boolean isFlag() {
return flag;
} public void setFlag(boolean flag) {
this.flag = flag;
} public int getStep() {
return step;
} public void setStep(int step) {
this.step = step;
}
}
Demo05.java
/**
* 使用collable接口创建线程
*
* @author :liuqi
* @date :2018-06-13 10:22.
*/
public class Demo05 {
public static void main(String[] args) throws InterruptedException,ExecutionException {
// 创建两个线程
ExecutorService ser = Executors.newFixedThreadPool(2);
Race tortoise = new Race("乌龟",1000);
Race rabbit = new Race("兔子",500);
// 获取future对象
Future<Integer> result1 = ser.submit(tortoise);
Future<Integer> result2 = ser.submit(rabbit);
// 2秒
Thread.sleep(2000);
// 停止线程体循环
tortoise.setFlag(false);
rabbit.setFlag(false);
// 获取值
int num1 = result1.get();
int num2 = result2.get();
System.out.println("乌龟跑了 " + num1 + "步");
System.out.println("兔子跑了 " + num2 + "步");
// 停止服务
ser.shutdownNow();
}
}
运行结果:
乌龟跑了 3步
兔子跑了 5步
代码地址:https://github.com/yuki9467/TST-javademo/tree/master/src/main/thread
Callable和Runnable有几点不同:
1.Callable规定方法是call(),而Runnable规定方法是run();
2.Callable任务执行后可返回值,而Runnable不能返回值;
3.call()可抛出异常,而run()不能抛出异常;
4.运行Callable任务可拿到一个Future对象,Future表示异步计算的结果,通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。