不调用期货清单

Not calling get on list of futures

我正在使用具有固定线程池大小的全局执行器服务。我们有一堆相关任务提交执行并等待期货清单。

最近,我们遇到了一个高 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 利用率?

http://www.journaldev.com/1650/java-futuretask-example-program

我仍然会像上面的例子一样检查 future isDone。

如果您需要 运行 其他操作或想更好地利用 CPU 那么我会将收集器放在一个单独的线程中,也许每分钟左右轮询一次结果。

可以由 Thread.sleep 安排或处理。

Executors class 提供了在线程池中执行 Callable 的各种方法。由于可调用任务 运行 并行,我们必须等待 returned 对象。

可调用任务 return java.util.concurrent.Future 对象。使用 Future 我们可以找出 Callable 任务的状态并获得 returned 对象。

它提供了 get() 方法,可以等待 Callable 完成,然后 return 结果。

get() 方法有一个重载版本,我们可以在其中指定等待结果的时间,这有助于避免当前线程长时间阻塞。

Future 提供了cancel() 方法来取消关联的Callable 任务。有 isDone() 和 isCancelled() 方法可以找出关联的 Callable 任务的当前状态。

这是一个简单的可调用任务示例,其中 return 是在随机时间后执行任务的线程的名称。 我们正在使用 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();
            }
        }
    }

}