次のスニペットで、を使用してもFutureTask
機能しない理由を誰かに教えてもらえますか?
私の理解では、私たちは使用できるということFutureTask
ですよね?
完全な説明をするために:
私は私のコードのいくつかの微妙なバグに出くわしました。簡単に言うと、パラメータとして渡されたを実行するために
を使用するクラスを作成しました。
バックグラウンドタスクを実行し、Eclipseアプリケーションで進行状況ダイアログを表示するために使用します。
コードは次のとおりです。 SingleThreadPoolExecutor
Callable
public class TaskRunner <T> {
final static ExecutorService threadPool = Executors.newSingleThreadExecutor();
private T taskResult;
public T runTask(Callable<T> task, Shell currentShell) throws CustomException{
if(currentShell == null){
currentShell = new Shell();
}
final Callable<T> taskToRun = task;
ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(currentShell);
try {
progressDialog.run(false, true, new IRunnableWithProgress() {
@SuppressWarnings("unchecked")
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
monitor.beginTask("Saving your data!", 100);
FutureTask<T> task = createTask(taskToRun);
Future<?> result = threadPool.submit(task);
while(!result.isDone()){
monitor.worked(1);
}
try {
taskResult = (T) result.get();
if(taskResult == null){
System.out.println("Result here in return is NULL!");
}
} catch (ExecutionException e1) {
logger.error(e1);
}
catch(Exception e){
logger.error(e);
}
}
});
} catch (InvocationTargetException e) {
logger.error(e);
} catch (InterruptedException e) {
logger.error(e);
}
return taskResult;
}
private static <T> FutureTask<T> createTask(Callable<T> theTask){
return new FutureTask<T>(theTask);
}
}
そしてコードタスク:
public class MyTask implements Callable<ComplexObject> {
private Util helper;
private String filePath;
public LoadKeystoreTask(Util helper, String filePath) {
this.helper = helper;
this.filePath = filePath;
}
@Override
public Container call() throws Exception {
ComplexObject result = helper.loadData(filePath);
if(result == null){
System.out.println("ComplexObject IS NULL!");
}
else{
System.out.println("ComplexObject IS NOT NULL!");
}
return result;
}
}
問題:
結果
はhelper.loadData
正しく返されますが(デバッグおよび印刷ステートメントで確認済み)、次の行があります。
taskResult = (T) result.get();
常にですnull
。
つまり、それを単純化するために印刷されます:
ComplexObjectはNULLではありません!
ここでの結果はNULLです!
これは、を送信したことが原因であることが確認されていますFutureTask
。代わり
に提出する場合:Callable
つまり、次のように変更します。
Future<?> result = threadPool.submit(taskToRun);
できます!FutureTask
でラップするとこの問題 が発生するのはなぜですか?