任何人都可以告诉为什么使用FutureTask
的以下代码段不起作用?
我的理解是我们可以使用FutureTask
,对吧?
为了给出完整的描述:
我在我的代码中偶然发现了一些微妙的错误
简单地说,我创建了一个使用SingleThreadPoolExecutor
运行Callable
作为参数传递的类
我使用它来运行后台任务并在Eclipse应用程序中显示进度对话框
代码是:
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 IS NOT NULL!
这里返回的结果是NULL!
这是通过提交FutureTask
来验证的
如果我提交Callable
代替:
即。只是改为:
Future<?> result = threadPool.submit(taskToRun);
它有效!为什么用FutureTask
包装会导致这个问题?
答案 0 :(得分: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
留给图书馆。
答案 1 :(得分:0)
这很简单。 FutureTask
为Runnable
,因此您调用ExecutorService
的确切方法为Future<?> submit(Runnable task)
。现在让我们来看看javadoc:
提交Runnable任务以执行并返回Future 代表那个任务。未来的get方法将会 成功完成后返回 null ...
这是可以理解的。 Runnable
仅包含void run()
方法。你希望它返回什么结果?
如果您向FutureTask
提交Executor
,只需使用它即可获得结果:
FutureTask<Integer> task = ...
threadPool.submit(task);
result = task.get();