与Runnable的比较

Runnable 缺少的一项功能是,当线程 终止时(即 run()完成时),我们无法使线程返回结果。为了支持此功能, Java 中提供了 Callable 接口。
image.png

  1. 为了实现 Runnable,需要实现不返回任何内容的 run()方法,而对于 Callable,需要实现在完成时返回结果的 call()方法。
  2. call()方法可以引发异常,而 run()则不能。
  3. 为实现 Callable 而必须重写 call 方法
  4. 不能直接替换 runnable,因为 Thread 类的构造方法根本没有 Callable 参数 ```java //实现Runnable接口 class MyThread1 implements Runnable { @Override public void run() {

    } }

//实现Callable接口 class MyThread2 implements Callable {

  1. @Override
  2. public Integer call() throws Exception {
  3. return 200;
  4. }

}

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

  1. 构造方法

image.png

  1. 两个常用方法:get()获取结果( 未完成则阻塞 get 方法,直到完成后再返回 ) ; isDone()判断是否计算结束
  2. 在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些 作业交给 Future 对象在后台完成 ; 当主线程将来需要时,就可以通过 Future 对象获得后台作业的计算结果或者执 行状态

  3. 代码演示: ```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");
   }

} //两个线程都结束后,主线程才结束 ``` image.png