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

问题描述 投票:2回答:2
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方法中设置时间限制?

java caching guava
2个回答
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

2
投票

由于MoreExecutors.sameThreadExecutor(),Paul Bellora所写的例子不起作用。

javadocsMoreExecutors.sameThreadExecutor()

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

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

© www.soinside.com 2019 - 2024. All rights reserved.