【问题标题】:How is the runner used to run the Callable in FutureTask<V>FutureTask<V> 中的 runner 是如何用来运行 Callable 的
【发布时间】:2018-09-30 19:05:25
【问题描述】:

source code of FutureTask&lt;V&gt; 中有一个volatile 实例变量 Thread runner,其中的注释告诉它是运行可调用对象的线程。但是,runner 从未在源代码中初始化。此外,我找不到任何线索如何使用这个runner 来运行可调用对象。

问题:由于runner从未初始化,如何使用它来运行Callable

【问题讨论】:

  • 在您链接到的源列表中,有一些使用runner 字段对sun.misc.Unsafe 的调用。我假设该字段由本机代码初始化。 UNSAFE.objectFieldOffset(k.getDeclaredField("runner"));
  • @markspace,我想你的意思是像UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) 这样的地方。 objectFieldOffset 只返回字段偏移量。

标签: java futuretask


【解决方案1】:

在代码中可以看到

if (state != NEW ||
        !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                     null, Thread.currentThread()))

run 方法的开头。忽略state != NEW 部分;这会尝试将runner 变量设置为Thread.currentThread() 的结果(并且仅当它当前为null 时才会成功)。只有成功(返回true),run 方法才能执行此块中的其余代码。而且由于Thread.currentThread() 的结果将是调用run 方法的Thread,因此文档是准确的(至少,在成功评估此初始if 部分之后)。

【讨论】:

  • 非常感谢:)除此之外,我觉得FutureTask就像是Callable(主题)的代理,不是吗?
  • @Rui ,是的,在某种程度上。 FutureTask结果是通过调用Callable得到的;但是添加了额外的功能(报告,只能调用一次等),这是简单的Callable item 所不提供的。
  • 另外值得注意的是,这只是FutureTask 的单一实现。其他 JDK 实现可能会选择委托给Callable(尽管我怀疑几乎所有理智的实现都会选择)。
猜你喜欢
  • 2013-08-20
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-03
  • 1970-01-01
相关资源
最近更新 更多