Как бегун используется для запуска Callable в FutureTask‹V›

В исходном коде FutureTask<V> есть является volatile переменной экземпляра Thread runner, где в комментарии сказано, что это поток, выполняющий вызываемый объект. Однако runner никогда не инициализируется в исходном коде. Более того, я не мог найти никакой подсказки, как этот runner используется для запуска callable.

Вопрос: поскольку runner никогда не инициализируется, как он используется для запуска Callable?


person Rui    schedule 30.09.2018    source источник
comment
В исходном листинге, на который вы ссылаетесь, есть несколько вызовов sun.misc.Unsafe с полем runner. Я предполагаю, что поле инициализировано собственным кодом. UNSAFE.objectFieldOffset(k.getDeclaredField("runner"));   -  person markspace    schedule 30.09.2018
comment
@markspace, я думаю, ты имеешь в виду такие места, как UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())). objectFieldOffset просто возвращает смещение поля.   -  person awesoon    schedule 30.09.2018


Ответы (1)


В коде вы можете увидеть

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

в начале метода run. Игнорирование части state != NEW; это пытается установить переменную runner в результат Thread.currentThread() (и будет успешным, только если в настоящее время она равна null). Только в случае успеха (возврат true) метод run сможет пройти остальную часть кода в этом блоке. И поскольку результатом Thread.currentThread() будет Thread, вызвавший метод run, документация является точной (по крайней мере, после того, как эта начальная часть if будет успешно оценена).

person BeUndead    schedule 30.09.2018
comment
Большое спасибо :) Вдобавок к этому, я чувствую, что FutureTask похож на прокси для Callable (субъекта), не так ли? - person Rui; 30.09.2018
comment
@Rui, да, в какой-то степени. результат FutureTask получается путем вызова Callable; однако добавлена ​​дополнительная функциональность (отчетность, возможность вызова только один раз и т. д.), которая не предоставляется простым элементом Callable. - person BeUndead; 30.09.2018
comment
Также стоит отметить, что это только одна реализация FutureTask. Другие реализации JDK могут предпочесть не делегировать Callable (хотя я подозреваю, что почти все разумные реализации будут). - person BeUndead; 30.09.2018