与Runnable的比较
Runnable 缺少的一项功能是,当线程 终止时(即 run()完成时),我们无法使线程返回结果。为了支持此功能, Java 中提供了 Callable 接口。
- 为了实现 Runnable,需要实现不返回任何内容的 run()方法,而对于 Callable,需要实现在完成时返回结果的 call()方法。
- call()方法可以引发异常,而 run()则不能。
- 为实现 Callable 而必须重写 call 方法
不能直接替换 runnable,因为 Thread 类的构造方法根本没有 Callable 参数 ```java //实现Runnable接口 class MyThread1 implements Runnable { @Override public void run() {
} }
//实现Callable接口 class MyThread2 implements Callable {
@Override
public Integer call() throws Exception {
return 200;
}
}
Callable构造线程的方法与runnable不同,无法像runnable一样直接在线程参数中添加接口实现类 Thread的构造函数中没有Callable接口的参数设置 public class Demo1 { public static void main(String[] args) throws ExecutionException, InterruptedException { //Runnable接口创建线程 new Thread(new MyThread1(),”AA”).start();
//Callable接口,~~~报错~~~
// new Thread(new MyThread2(),"BB").start();
}
}
<a name="lMVSU"></a>
## 解决方法--FutureTask
![image.png](https://cdn.nlark.com/yuque/0/2021/png/22137958/1632104436542-593f37e4-efac-4e2d-bf3a-ef39e1804d90.png#clientId=u731882b2-8cef-4&from=paste&height=339&id=u59607b69&margin=%5Bobject%20Object%5D&name=image.png&originHeight=339&originWidth=645&originalType=binary&ratio=1&size=83675&status=done&style=none&taskId=u81f08925-f440-462f-8a21-091e0ad47aa&width=645)
<a name="VPhiZ"></a>
# 使用Callable创建线程
1. 创建方式
2. 使用实现类
2. 使用lamda表达式(Callable为函数式接口)
```java
//实现Callable接口 方式一
class MyThread2 implements Callable {
@Override
public Integer call() throws Exception {
return 200;
}
}
FutureTask<Integer> futureTask1 = new FutureTask<>(new MyThread2());
===============================================================
//lam表达式 方式二
FutureTask<Integer> futureTask2 = new FutureTask<>(()->{
System.out.println(Thread.currentThread().getName()+" come in callable");
return 1024;
});
FutureTask
- 构造方法
- 两个常用方法:get()获取结果( 未完成则阻塞 get 方法,直到完成后再返回 ) ; isDone()判断是否计算结束
在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些 作业交给 Future 对象在后台完成 ; 当主线程将来需要时,就可以通过 Future 对象获得后台作业的计算结果或者执 行状态
代码演示: ```java //比较两个接口 //实现Runnable接口 class MyThread1 implements Runnable { @Override public void run() {
} }
//实现Callable接口 class MyThread2 implements Callable {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName()+" come in callable");
return 200;
}
}
public class Demo1 { public static void main(String[] args) throws ExecutionException, InterruptedException { //Runnable接口创建线程 new Thread(new MyThread1(),”AA”).start();
//FutureTask
FutureTask<Integer> futureTask1 = new FutureTask<>(new MyThread2());
//lam表达式
FutureTask<Integer> futureTask2 = new FutureTask<>(()->{
System.out.println(Thread.currentThread().getName()+" come in callable");
return 1024;
});
//创建一个线程
new Thread(futureTask2,"lucy").start();
new Thread(futureTask1,"mary").start();
// while(!futureTask2.isDone()) { // System.out.println(“wait…..”); // } //调用FutureTask的get方法 System.out.println(futureTask2.get());
System.out.println(futureTask1.get());
System.out.println(Thread.currentThread().getName()+" come over");
}
}
//两个线程都结束后,主线程才结束
```