直接继承Thread或者实现Runnable接口、在执行完任务之后无法获取执行结果。
从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果
Callable介绍
callable接口只有一个方法,call(),是线程实际的业务逻辑方法。
@FunctionalInterface注解解释:
是JDK 8 中新增的注解类型,用来描述一个接口是函数式接口。
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
函数式接口可以使用 lambda 表达式、方法引用、构造函数引用来创建。这里不做过多介绍。
函数式接口可以被隐式转换为 lambda 表达式。
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
Future介绍
future接口方法介绍:
cancel() 取消任务,取消任务成功则返回true,取消任务失败则返回false。
参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果=true,则表示可以取消正在执行过程中的任务。
取消已经完成的任务会返回false。
如果任务正在执行,mayInterruptIfRunning=true,则返回true,若mayInterruptIfRunning=false,则返回false。
如果任务还没有执行,则返回true。
isCancelled() 任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
isDone() 任务是否已经完成 。
get() 获取执行结果,该方法会阻塞,一直等到任务执行完毕才返回;
get(long timeout, TimeUnit unit) 获取执行结果,如果在指定时间内,还没获取到结果,就返回null
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
FutureTask介绍
public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V>
FutureTask实现了RunnableFuture接口,而 RunnableFuture继承了Runable和Future。
所以FutureTask既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
代码演示
1.Callable+Future
package com.sid.util.FutureTask;
import java.util.concurrent.*;
/**
* @program: springboot
* @description: 使用Callable+Future获取执行结果
* @author: Sid
* @date: 2018-11-20 10:57
* @since: 1.0
**/
public class FutureTest {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
Task task = new Task();
Future<Integer> result = executor.submit(task);
executor.shutdown();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("Thread main is running...");
try {
System.out.println("Thread task result is:"+result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("All Thread done");
}
}
/**
* @program: springboot
* @description:
* @author: Sid
* @date: 2018-11-20 11:09
* @since: 1.0
**/
public class Task implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("Thread task is running...");
Thread.sleep(3000);
int sum = 0;
for(int i=0;i<10;i++)
sum += i;
return sum;
}
}
结果
Thread task is running...
Thread main is running...
Thread task result is:45
All Thread done
2. Callable+FutureTask
package com.sid.util.FutureTask;
import java.util.concurrent.*;
/**
* @program: springboot
* @description:
* @author: Sid
* @date: 2018-11-20 11:08
* @since: 1.0
**/
public class FutureTaskTest {
public static void main(String[] args) {
//第一种方式,使用executor.submit();
ExecutorService executor = Executors.newCachedThreadPool();
Task task = new Task();
FutureTask<Integer> futureTask = new FutureTask(task);
executor.submit(futureTask);
executor.shutdown();
//第二种方式,使用的是thread.start()
/*Task task = new Task();
FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
Thread thread = new Thread(futureTask);
thread.start();*/
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("Thread main is running...");
try {
System.out.println("Thread task result is:"+futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("All Thread done");
}
}
结果
Thread task is running...
Thread main is running...
Thread task result is:45
All Thread done