我们使用继承Thread类,实现Runable类实现线程的时候,都面临一个问题,那就是在run方法里面无法抛异常,无法获取线程执行完后的返回值,我们需要返回值的时候怎么办呢?这个时候就需要 实现Callable接口了
我们来做一个龟兔赛跑的小实验
第一个,写出一个赛跑类,里面包含 赛跑者的名字,速度,是否可以跑,跑的总步数几个字段,
/**
* 创建赛跑类
* @author snow
*
*/
class Race implements Callable<Integer> {
// 赛跑者的名字
private String name;
// 延时多少
private Long time ;
// 跑了多少步
private int step;
// 标志是否能跑
private boolean flag;
public Race(String name, Long time, boolean flag) {
super();
this.name = name;
this.time = time;
this.flag = flag;
}
// 省略get,set方法
@Override
public Integer call() throws Exception {
// 只有当 flag 为 true 的时候才赛跑
while(this.flag) {
Thread.sleep(this.time);
this.step++;
System.out.println(this.name+"--跑了--"+this.step+"步");
}
return this.step;
}
}
方法调用,注意看代码上的注释:
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 实例化Callable的实例
Race tortoise = new Race("乌龟", 1000L, true);
Race rabbit = new Race("兔子", 300L, true);
// new 两个线程,固定线程
ExecutorService service = Executors.newFixedThreadPool(2);
// 需要获取返回值的时候使用 线程.submit(Callable<T>) 返回 Futrue 对象,使用 Futrue.get() 方法获取返回值
Future<Integer> tortoiseSer = service.submit(tortoise);
Future<Integer> rabbitSer = service.submit(rabbit);
// 线程休眠5秒,五秒后停止赛跑
Thread.sleep(5000);
tortoise.setFlag(false);
rabbit.setFlag(false);
int tortoisStep = tortoiseSer.get();
int rabbitStep = rabbitSer.get();
System.out.println( "乌龟一共跑了--"+tortoisStep+"--步" );
System.out.println( "兔子一共跑了--"+rabbitStep+"--步" );
// 关闭服务,ExecuteServer 执行完毕之后并不会自己关闭服务,需要手动关闭
service.shutdownNow();
}
运行效果: