3

次のスニペットで、を使用してもFutureTask機能しない理由を誰かに教えてもらえますか?
私の理解では、私たちは使用できるということFutureTaskですよね?
完全な説明をするために:
私は私のコードのいくつかの微妙なバグに出くわしました。簡単に言うと、パラメータとして渡されたを実行するために
を使用するクラスを作成しました。 バックグラウンドタスクを実行し、Eclipseアプリケーションで進行状況ダイアログを表示するために使用します。 コードは次のとおりです。 SingleThreadPoolExecutorCallable

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でラップするとこの問題 が発生するのはなぜですか?

4

2 に答える 2

2

FutureTaskここでは不要です:

private static <T> FutureTask<T> createTask(Callable<T> theTask){  
    return new FutureTask<T>(theTask);   
}

FutureTask<T> task = createTask(taskToRun);  
Future<?> result = threadPool.submit(task); 

直接submit() Calleble<T>

Future<?> result = threadPool.submit(taskToRun); 

FutureTaskユーザーコードで使用するためのものではないと思います:

このクラスは、の基本実装を提供しますFuture

実装Futureはライブラリに任せてください。

于 2012-10-27T20:55:21.590 に答える
0

それはとても簡単です。あなたが呼び出す正確な方法はそうFutureTaskです. それでは、javadoc を見てみましょう。RunnableExecutorServiceFuture<?> submit(Runnable task)

Runnable タスクを実行のために送信し、そのタスクを表す Future を返します。Future の get メソッドは、正常に完了するとnullを返します...

それはとても理解できます。メソッドRunnableのみが含まれます。void run()どのような結果を返したいですか?

FutureTask結果を取得するためだけに使用するために送信する場合Executor:

FutureTask<Integer> task = ...
threadPool.submit(task);
result = task.get();
于 2012-11-30T00:10:40.973 に答える