我相信我理解Future / Callable如何运作良好。与下面的代码(第2部分)类似,cacheLoader1和cacheLoader2是Callable实现的两个实例,其call()方法是加载缓存
@Override
public Cache call() throws Exception {
cache.loadCache();
return cache;
}
我打算使用两个线程来运行任务并合并返回的缓存。我理解未来#get()将阻塞,直到相应的线程完成。然而,我遇到的问题是永远不会回来。我注释掉了Future#get()的单行,然后就继续了。
我查看了缓存#loadCache()中的代码,发现它尝试从DB表中检索数据,比如service.getData(),在它下面调用DAO,后者又使用Spring的getSqlMapClientTemplate和iBatis SQL 。如果我恢复注释的Future#get,DAO永远不会返回。
List<Future<Cache>> list = new ArrayList<Future<Cache>>();
Future<Cache> f = es.submit(cacheLoader1);
list.add(f);
f = es.submit(cacheLoader2);
list.add(f);
for(Future<Cache> future: list){
logger.debug("done with {}",future.get());
}
我很难理解可能出错的地方。有帮助吗?那是因为在调用方法中抛出了Exception子句吗?
P.S。进一步澄清:
ExecutorService es = Executors.newFixedThreadPool(2);
class CacheLoader implements Callable<Cache>{
....
@Override
public Cache call() throws Exception {
cache.loadCache();
return cache;
}
}
CacheLoader cacheLoader1, cacheLoader2;
更新:
我似乎找出了根本原因,但需要建议最佳解决方案。首先我道歉,早期的信息不足以让人们查明问题。
这是一个Spring项目,第二部分的代码位于 init-method 中,名为&#34; init &#34;一个豆子。上述DAO也在Spring注册。所以问题似乎是方法&#34; init&#34;正在挂起块f.get()的bcoz并且Spring配置无法完成;它是一种循环依赖吗?我仍然没有找到最佳方法......
谢谢,
乔恩
答案 0 :(得分:0)
我找到了解决方案,很容易。
在init-method中,我创建了另一个线程,如下面的
ExecutorService es = Executors.newFixedThreadPool(2);
es.execute(cacheLoader);
和CacheLoader实现Runnable( es1 是ExecuteService的另一个实例):
public class CacheLoader implements Runnable{
public void run() {
Future<Cache> f1 = es1.submit(new Callable<Cache>(){
@Override
public Cache call(){
cache1.loadCache();
return cache1;
}
});
Future<Cache> f2 = es1.submit(new Callable<Cache>(){
@Override
public Cache call(){
cache2.loadCache();
return cache2;
}
});
Cache c1 = f1.get();
Cache c2 = f2.get();
} //~end of run() ~
}