我正在使用java.util.concurrency框架实现一些代码.我将把一组callables传递给一个将并行执行它们的类.我正试图找出以类型安全的方式获取每个响应的最佳方法.这里有一些代码可以帮助解释我在做什么:
首先我创建我的Callables,这是要并行调用的工作单元.例如,这里第一个工作单元返回a String,第二个工作单元返回Integer:
Callable<String> firstCallable = new Callable<String>(){
public String call() {...}
};
Callable<Integer> secondCallable = new Callable<Integer>(){
public Integer call() {...}
};
Run Code Online (Sandbox Code Playgroud)
现在我将它们激活到我的框架中以并行运行它们,并且诀窍是获得适当的响应对象的句柄.这是一个有效的实现:
Map<Callable,Object> responseMap = ParallelSender.send(firstCallable,
secondCallable);
Run Code Online (Sandbox Code Playgroud)
Object特定的响应在哪里Callable.因此,你可以这样做:
String firstCallableResponse = (String)responseMap.get(firstCallable);
Integer secondCallableResponse = (Integer)responseMap.get(secondCallable);
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,从地图中获取时是否可以避免投射?这不会编译,但我正在考虑这些方面:
Map<Callable<T>, T> responseMap = ParallelSender.send(...);
String firstCallableResponse = responseMap.get(firstCallable);
Run Code Online (Sandbox Code Playgroud)
这样返回的值基于Callable键的类型参数.我担心的是,如果有人refactors工作单位的返回类型(从说Integer来BigDecimal,然后自投或其他)Object永远不会被自动重构工具被捕获,并可能导致运行时问题.
结论:感谢下面的所有有用的评论和讨论,我采取了一个略有不同的机智(尽管肖恩帕特里克弗洛伊德认为上面的问题是正确的).我最终完全删除了响应映射并Callable用响应填充了对象.以下是相关的代码段:
public abstract class AbstractParallelCallable<V> implements Callable<V> {
/** The response generated by the Call method of this class. */
private V callableResponse;
public V getResponse() {
return callableResponse;
}
public void setResponse(V response) {
callableResponse = response;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,我有一个抽象实现,它通过存储响应来包装Callable对象.接下来,在我的并行处理中,我得到每个Future创建的响应并填充AbstractParallelCallable:
for (ParallelFutureTask<Object> future : futures) {
try {
future.getCallableHandle().setResponse(future.get());
} catch(Exception e) {...}
}
Run Code Online (Sandbox Code Playgroud)
其中getCallableHandle返回AbstractParallelCallable对象,ParallelFutureTask通过提供对Callable对象的引用来包装FutureTask.执行后,调用代码可以执行以下操作:
Integer theResult = firstCallable.getResponse();
Run Code Online (Sandbox Code Playgroud)
你能做到的唯一方法是将它封装在一个方法中:
class ParallelSender{
private final Map<Callable<?>, Object> map =
new HashMap<Callable<?>, Object>();
@SuppressWarnings("unchecked")
public <T> T getResult(final Callable<T> callable){
return (T) map.get(callable);
}
}
Run Code Online (Sandbox Code Playgroud)
现在您的客户端代码不需要强制转换:
ParallelSender parallelSender = new ParallelSender();
Callable<Integer> integerCallable = new Callable<Integer>(){
@Override
public Integer call() throws Exception{
return Integer.valueOf(1);
}
};
Integer result = parallelSender.getResult(integerCallable);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1063 次 |
| 最近记录: |