没有打电话到期货清单

时间:2015-01-10 07:44:35

标签: java multithreading concurrency future executorservice

我正在使用具有一些固定线程池大小的全局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利用率?

2 个答案:

答案 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();
            }
        }
    }

}