31.Java Callable 接口与 FutureTask 类
一、Callable 接口
1、概述
- 目前我们学习了有两种创建线程的方法,一种是通过继承 Thread 类,另一种是
通过实现 Runnable 接口创建线程,但是,Runnable 缺少的一项功能是,当线程
终止时(即 run 方法完成时),无法使线程返回结果,为了支持此功能,Java 中提供了 Callable 接口
2、Callable 接口对比 Runnable 接口
-
实现 Runnable 接口,需要实现无返回值的 run 方法,实现 Callable 接口,需要实现在有返回值的 call 方法
-
run 方法不会抛出异常,call 方法会抛出异常
3、实现 Runnable 接口和 Callable 接口
class MyThread1 implements Runnable {
@Override
public void run() {
System.out.println("实现 Runnable 接口");
}
}
class MyThread2 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("实现 Callable 接口");
return 100;
}
}
4、Callable 实现线程创建问题
-
Thread 类的构造器不支持接收 Callable 实现
-
需要寻找一个类,既和 Runnable 接口有关,又和 Callable 接口有关
-
FutureTask 类满足条件,该类实现了 Runnable 接口,构造器支持接收 Callable 实现
二、FutureTask 类
1、构造器
- 创建一个 FutureTask 对象,一旦运行就执行 Callable 实现
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW;
}
- 创建一个 FutureTask 对象,一旦运行就执行 Runnable 实现,并安排成功完成时 get 方法返回给定的 result
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW;
}
2、常用方法
方法 | 说明 |
---|---|
get() | 获取结果 |
boolean isDone() | 判断是否执行完毕 |
3、基本使用
package com.my.callable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// Runnable
Thread thread1 = new Thread(new MyThread1(), "AA");
// Callable
FutureTask futureTask1 = new FutureTask(new MyThread2());
FutureTask<Integer> futureTask2 = new FutureTask(() -> {
System.out.println(Thread.currentThread().getName() + " 实现了 Callable 接口");
return 200;
});
FutureTask<Integer> futureTask3 = new FutureTask<Integer>(new MyThread1(), 300);
Thread thread2 = new Thread(futureTask1, "BB");
Thread thread3 = new Thread(futureTask2, "CC");
Thread thread4 = new Thread(futureTask3, "DD");
// 开启线程
thread1.start();
thread2.start();
thread3.start();
thread4.start();
Thread.sleep(1000);
// isDone 方法
System.out.println(futureTask1.isDone());
System.out.println(futureTask2.isDone());
System.out.println(futureTask3.isDone());
// get 方法
System.out.println(futureTask1.get());
System.out.println(futureTask2.get());
System.out.println(futureTask3.get());
}
}
class MyThread1 implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 实现了 Runnable 接口");
}
}
class MyThread2 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + " 实现了 Callable 接口");
return 100;
}
}
原文地址:https://blog.csdn.net/weixin_52173250/article/details/145216517
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!