一、线程的提前完成任务
1、Future的使用
-
结合Callable使用,使用一个 FutureTask 来包装Callable对象,而FutureTask是实现了Future和Runnable接口的,故可用Thread包装FutureTask的对象,然后调用start方法启动线程;
可见 FutureTask 是 Runnable 的子类
使用 Future 和 Callable 开启一个线程
/**
* Callalbe和Runnable的区别
*
* Runnable run方法是被线程调用的,在run方法是异步执行的
*
* Callable的call方法,不是异步执行的,是由Future的run方法调用的
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 1、创建一个 Callable线程
Callable<Integer> call = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println("正在执行call...");
Thread.sleep(3000);
return 1;
}
};
// 2、使用FutureTask包装Callable线程
FutureTask<Integer> task = new FutureTask<>(call);
// 3、使用Thread 包装FutureTask来启动线程
Thread thread = new Thread(task);
thread.start(); // 启动线程
// 此时主线程可以做别的事情,之后再获取Callable线程执行完毕的返回值
System.out.println(" 主线程在运行1...");
Integer result = task.get(); // 注:在拿结果的时候会阻塞当前线程
System.out.println(" 主线程在运行2...");
System.out.println("拿到call的结果为:" + result);
}
* Callalbe和Runnable的区别
* Runnable run方法是被线程调用的,在run方法是异步执行的
* Callable的call方法,不是异步执行的,是由Future的run方法调用的
-
FutureTask的源码
-
由于FutureTask是由Thread包装并用start启动的线程,故启动了FutureTask的run方法
-
run方法中通过 Callable的对象调用了call方法
-
get方法中通过FutureTask的状态值来对当前线程做yield、wait或return操作
-
FutureTask 部分源码解析
public class FutureTask<V> implements RunnableFuture<V> {
// 几个状态值
private volatile i