当前位置: 代码迷 >> 综合 >> JUC学习系列十(异步计算 FutureTask)
  详细解决方案

JUC学习系列十(异步计算 FutureTask)

热度:7   发布时间:2023-12-28 12:34:01.0
public interface Future<V>
Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。

Future接口的族谱结构:

 FutureTask的介绍和使用:

可取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对 Future 的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。可使用 FutureTask 包装 CallableRunnable 对象。因为 FutureTask 实现了 Runnable,所以可将 FutureTask 提交给 Executor 执行。除了作为一个独立的类外,此类还提供了 protected 功能,这在创建自定义任务类时可能很有用。

使用案例:

public class FutureTest {public static void main(String[] args) {//方式一  FutureTask(Callable<V> callable)Callable<Integer> call=new Callable<Integer>() {@Overridepublic Integer call() throws Exception {System.out.println("正在处理计算结果...");TimeUnit.SECONDS.sleep(1);return 27;}};//方式二   FutureTask(Runnable runnable, V result)Runnable run=new Runnable() {@Overridepublic void run() {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("处理完毕...");}};
//        FutureTask<Integer> task=new FutureTask<Integer>(call);  //方式一FutureTask<Integer> task=new FutureTask<Integer>(run,27);//方式二new Thread(task).start();System.out.println("其他的任务处理中...");try {Integer result=task.get();System.out.println("获得计算结果"+result);} catch (Exception e) {e.printStackTrace();}}}

 案例执行结果:

FutureTask实现Runable接口,可以放到Thread()里面执行。它的构造方法需要一个runnable实例或者callable实例:

线程启动后,调用FutureTask的get方法,就会阻塞着等待结果输出。

源码解析:(比较粗略,这个类和CAS相关,有很多偏移量(XXXoffset)的成员变量,并用了一个waitNode的内部类管理阻塞线程。一些方法,能猜到它是干嘛的,但是分解每一步还有些疑惑之处)

构造方法:

FuturnTask是一个线程任务类,所以关键的还是其run方法: