织梦网站后台管理,中级网站开发工程师 试题,wordpress首页文章数量,室内设计欣赏网站文章目录 1.介绍2.使用示例3.执行过程描述4.整体的关系5.涉及到的核心源码#xff08;只提取了关键代码#xff09;5.1 Callable5.2 RunnableFuture5.3 FutureTask5.4 Thread 1.介绍
FutureTask 能够接收 Callable 类型的参数#xff0c;用来处理有返回结果的情况。
2.使用… 文章目录 1.介绍2.使用示例3.执行过程描述4.整体的关系5.涉及到的核心源码只提取了关键代码5.1 Callable5.2 RunnableFuture5.3 FutureTask5.4 Thread 1.介绍
FutureTask 能够接收 Callable 类型的参数用来处理有返回结果的情况。
2.使用示例
// 创建任务对象
FutureTaskInteger task new FutureTask(() - {log.debug(running);Thread.sleep(1000);return 200;
});new Thread(task).start();// 主线程阻塞同步等待 task 执行完毕的结果
Integer value task.get();System.out.println(value value);3.执行过程描述
FutureTask 类在实例化构造时需要传入一个实现了 Callable 接口的类实现 Callable 接口需要重写 call 方法该方法需要一个返回值由于 Callable 定义时是以泛型定义返回值因此我们可以自定义返回值。FutureTask 会将传入的这个 Callable 实现类赋给自己的属性 private CallableV callable;FutureTask 间接实现了 Runnable 接口并重写了 run 方法重写的 run 方法中会调用到 属性 callable 的 call 方法并将 call 方法返回值存储到自己的属性 private Object outcome;Thread 类在实例化构造时可以传入一个 Runnable 接口的类由于 FutureTask 实现了 Runnable 接口因此我们可以直接将 FutureTask 对象作为构造器实参赋给 Thread对象的属性 private Runnable target;Thread 对象调用 start 方法最终会调用到自身就重写了的 run 方法自身重写的 run 方法中又会调用到 target 的 run 方法即 FutureTask 自身已经重写的 run 方法这时候就可以回到“第 2 点讲解”了解到 FutureTask 的 run 方法中所做的事情。FutureTask 对象的 get() 方法是去获取 callable 的 call 方法返回值即属性 outcome 的值。get 方法中会调用 awaitDone 方法awaitDone 方法中会使用 for (;;) 造成当前线程阻塞直到 call 方法执行结束可以获取到 outcome 的值并将 outcome 作为 get() 方法返回值。
4.整体的关系
Thread 和 FutureTask 类均实现了 Runnable 接口并重写了其 run 方法Thread 将 FutureTask 进行聚合赋给 private Runnable target。
5.涉及到的核心源码只提取了关键代码
5.1 Callable
FunctionalInterface
public interface CallableV {/*** 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;
}5.2 RunnableFuture
public interface RunnableFutureV extends Runnable, FutureV {/*** Sets this Future to the result of its computation* unless it has been cancelled.*/void run();
}5.3 FutureTask
public class FutureTaskV implements RunnableFutureV {/** The underlying callable; nulled out after running */private CallableV callable;// 存储 callable 接口的 call 方法的返回值/** The result to return or exception to throw from get() */private Object outcome; // non-volatile, protected by state reads/writes/*() - {log.debug(running);Thread.sleep(1000);return 200;}这实际上是对函数式接口 callable 的 V call() 方法进行实现*/public FutureTask(CallableV callable) {if (callable null)throw new NullPointerException();this.callable callable;this.state NEW; // ensure visibility of callable} public void run() {// ...CallableV c callable;// 重写了 Runnable 函数式接口的 run 方法result c.call();// ...// 赋值set(result);// ...}protected void set(V v) {if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {// 将 callable 的 call 方法返回值即我们自定义的 200 赋给 outcomeoutcome v;UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final statefinishCompletion();}}// 获取 callable 的 call 方法的返回结果public V get() throws InterruptedException, ExecutionException {int s state;if (s COMPLETING)// 获取到结果成功的标识实际是在 awaitDone 方法中用了死循环不断判断是否生成返回结果造成了线程阻塞s awaitDone(false, 0L);// 获取结果return report(s);}// timed-是否计时等待即是否设置等待超时false表示不设置true表示设置private int awaitDone(boolean timed, long nanos)throws InterruptedException {final long deadline timed ? System.nanoTime() nanos : 0L;WaitNode q null;boolean queued false;// 死循环for (;;) {if (Thread.interrupted()) {removeWaiter(q);throw new InterruptedException();}int s state;if (s COMPLETING) {if (q ! null)q.thread null;return s;}else if (s COMPLETING) // cannot time out yetThread.yield();else if (q null)q new WaitNode();else if (!queued)queued UNSAFE.compareAndSwapObject(this, waitersOffset,q.next waiters, q);else if (timed) {nanos deadline - System.nanoTime();if (nanos 0L) {removeWaiter(q);return state;}LockSupport.parkNanos(this, nanos);}elseLockSupport.park(this);}}
}5.4 Thread
public class Thread implements Runnable {/* What will be run. */private Runnable target;// 构造器将间接实现了 Runnable 接口的 FutureTask 对象传进来public Thread(Runnable target) {init(null, target, Thread- nextThreadNum(), 0);}private void init(ThreadGroup g, Runnable target, String name, long stackSize) {init(g, target, name, stackSize, null, true);}private void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc,boolean inheritThreadLocals) {// ...// 将 FutureTask 对象赋给 Thread 对象的属性 targetthis.target target;}Overridepublic void run() {if (target ! null) {// 实际调用的 FutureTask 对象重写的 run 方法重写的 run 方法中又会调用 callable 接口的 call 方法并将 call 方法的返回值赋给 FutureTask 对象的属性 outcometarget.run();}}
}