代码之家  ›  专栏  ›  技术社区  ›  Nikolas Charalambidis

如何使用Spring Boot清除@Async任务的所有已完成的未来结果?

  •  2
  • Nikolas Charalambidis  · 技术社区  · 6 年前

    我很难理解 @Async

    我有一些 Map<Integer, String> map 我想更新一下 map 使用异步方法调用。这种方法使 HTTP GET int id 又回来了 String string 结果-它被更新为 地图

    @Async
    public Future<Entry<Integer, String>> updateEntry(Integer key, String value) {
        Entry<Integer, String> entry = // Method call updates String value (let's say HTTP GET request takes few seconds)
        return new AsyncResult<Entry<Integer, String>>(entry);
    }
    

    因为如果使用 this ,有另一个类正在执行这些方法:

    private final Map<Integer, String> map = new ConcurrentHashMap<>();
    
    private void update() {
    
        // KICK THE ASYNC METHODS UP
        List<Future<Entry<Integer, String>>> futures = new ArrayList<>();
        map.forEach((key, value) -> {
            futures.add(asyncObject.updateEntry(value));
        }); 
    
        // FETCH THE RESULTS
        Iterator<Future<Entry<Integer, String>>> iterator = futures.iterator();
        while (iterator.hasNext()) {
            Future<Entry<Integer, String>> future = iterator.next();
            if (future.isDone()) {
                try {
                    Entry<Integer, String> entry = future.get();
                    this.map.put(entry.getKey(), entry.getValue());
                    iterator.remove();
                } catch (InterruptedException | ExecutionException e) {
                    // SH*T HAPPENS, LOG IT
                }
            }
            if (!iterator.hasNext()) {
                iterator = futures.iterator();
            }
        }
    }
    

    我把所有未来的结果都储存在 futures while-loop 检查是否 Future::isDone ,上面的迭代简要描述如下:

    1. 迭代 未来 endless Iterator .
    2. 如果 Future<Entry<Integer, String>> 完成时间:
      • Map::put 替换了条目
      • 删除 未来<输入<整数,字符串>> List
    3. 如果列表 未来

    这个解决方案(我的第一个多线程实验)出人意料地奏效了。

    这个解决方案是线程安全的,方法正确吗?是指 ConcurrentHashMap 地图 将由另一个 @异步 update 方法调用-将使此方法 synchronized 够了吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Georgy Gobozov    6 年前

    对我来说,方法看起来不错。如果在 update 方法运行自 ConcurrentHashMap 使用。如果你想防止同时 更新 跑你能做的方法 synchronized CompletableFuture allOf