我正在使用具有一些固定线程池大小的全局Executor服务。我们有许多相关的任务,我们提交执行并等待期货清单。
最近,我们遇到了高CPU使用率问题,并且在调试时我发现在期货列表中的某个项目上调用get()时发生了异常。当前,我们遍历列表并且围绕整个循环有一个try catch。
try{
List<Result> results = new ArrayList<>()
for(Future<Result> futureResult: futureResults{
Result result = futureResult.get();
results.add(result);
}
} catch(Exception e){
throw new InternalServiceException(e);
}
//Do something with results
如果将来某些项目从未调用过get,则想知道其他线程的行为。我试过搜索但是找不到任何东西。
此外,此行为是否会触发高CPU利用率?
答案 0 :(得分:1)
http://www.journaldev.com/1650/java-futuretask-example-program
我仍然会检查未来是否如上例所示。
如果您需要运行其他操作或想要更好地利用CPU,那么我会将收集器放在一个单独的线程中,也许只是每分钟左右轮询结果。
可以由Thread.sleep安排或处理。
答案 1 :(得分:0)
Executors类提供了在线程池中执行Callable的各种方法。由于可调用任务并行运行,我们必须等待返回的Object。
可调用任务返回java.util.concurrent.Future对象。使用Future我们可以找出Callable任务的状态并获取返回的Object。
它提供了get()方法,可以等待Callable完成然后返回结果。
有一个get()方法的重载版本,我们可以指定等待结果的时间,这对于避免当前线程被阻塞更长时间很有用。
Future提供cancel()方法来取消关联的Callable任务。有isDone()和isCancelled()方法来查找关联的Callable任务的当前状态。
这是一个简单的Callable任务示例,它返回在一些随机时间后执行任务的线程的名称。 我们使用Executor框架并行执行10个任务,并使用Future来获取提交任务的结果。
public class FutureObjectTest implements Callable<String>{
@Override
public String call() throws Exception {
long waitTime = (long) (Math.random()*10000);
System.out.println(Thread.currentThread().getName() + " waiting time in MILISECONDS " + waitTime);
Thread.sleep(waitTime);
return Thread.currentThread().getName() + " exiting call method.";
}
public static void main(String [] args){
List<Future<String>> futureObjectList = new ArrayList<Future<String>>();
ExecutorService executorService = Executors.newFixedThreadPool(5);
Callable<String> futureObjectTest = new FutureObjectTest();
for(int i=0; i<10; i++){
Future<String> futureResult = executorService.submit(futureObjectTest);
futureObjectList.add(futureResult);
}
for(Future<String> futureObj : futureObjectList){
try {
System.out.println(futureObj.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("Starting get method of wait");
////////////get(Timeout) method///////
futureObjectList.clear();
for(int i=0; i<10; i++){
Future<String> futureResult = executorService.submit(futureObjectTest);
futureObjectList.add(futureResult);
}
executorService.shutdown();
for(Future<String> futureObj : futureObjectList){
try {
System.out.println(futureObj.get(2000,TimeUnit.MILLISECONDS));
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
}
}
}