如何使用限制时间的番石榴缓存加载功能?

时间:2013-08-23 03:25:19

标签: java caching guava

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) throws AnyException {
               return createExpensiveGraph(key);
             }
           });

createExpensiveGraph方法可能需要很长时间才能返回值。我想在load方法中设置一个时间限制,这样如果createExpensiveGraph方法在限定时间内没有返回值,则抛出TimeLimitedException。如何在load方法中设置时间限制?

2 个答案:

答案 0 :(得分:4)

修改已更正为使用newSingleThreadExecutor作为pointed out by eclps

您可以使用CallableExecutorService来实现超时行为:

final ExecutorService executor = Executors.newSingleThreadExecutor();

final LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .build(
           new CacheLoader<Key, Graph>() {
               public Graph load(final Key key) throws Exception {
                   return executor.submit(new Callable<Graph>() {
                       @Override
                       public Graph call() {
                           return createExpensiveGraph(key);
                       }
                   }).get(MY_TIME_LIMIT_SECONDS, TimeUnit.SECONDS);
               }
           });

get通话网站:

final Graph graph;
try {
    graph = graphs.get(myKey);
}
catch (ExecutionException executionException) {
    final Throwable cause = Throwables.getRootCause(executionException);
    if (cause instanceof TimeoutException) {
        // timeout specific logic
    }
    // other error handling
}

// use graph

答案 1 :(得分:2)

由于MoreExecutors.sameThreadExecutor(),Paul Bellora的书面示例无效。

来自MoreExecutors.sameThreadExecutor()的{​​{3}}:

  

在将Future返回给调用者之前,任务运行完成(除非执行程序已关闭)。

因此,在get完成执行之后才会调用Future上的createExpensiveGraph。使用Executors.newSingleThreadExecutor()或类似的Executor来支持超时。