首页 > 解决方案 > 使用 Executors 时的空 Map

问题描述

我试图在给定的时间范围内,每分钟计算与typea 中的参数相同的记录。List使用以下方法:

public Map<String, Object> getCountPerMinuteForType(final String type,
                                 final long startTimestamp,
                                 final long endTimestamp) {
    final Map<String, Object> countsPerMinForType = new HashMap<>();
    Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            int counter = 0;
            List<Data> dataList = storage.retrieveData();
            for(Data data: dataList){
                if (data.getType().equals(type) &&
                    data.getUnixTimestamp() >= startTimestamp &&
                    data.getUnixTimestamp() <= endTimestamp){
                    counter++;
                }
            }
            countsPerMinForType.put(type, counter);
        }, 0, 1, TimeUnit.MINUTES);
    return countsPerMinForType;
}

问题是,这个方法返回一个空的Map

当我打印Map里面的内容时Executors,我可以看到它有数据。

标签: java

解决方案


您遇到的问题是您期望您正在剥离的线程已完成工作并countsPerMinForType返回填充的结果。这不是正在发生的事情......

正在发生的事情是:

  1. 您从执行的主/当前线程调用该方法
  2. Map创建
  3. 一个新线程被剥离出来做一些工作
  4. 几乎立即,该方法返回并且地图仍然是空的。...
  5. 方法完成后,将执行分拆线程正在执行的工作......随后调用方法永远不会看到结果。

您可以通过一个测试来确认这种情况,该测试在开始和结束时返回一个timestamp,在getCountPerMinuteForType开始和结束timestamp时返回另一个Thread。开始时间将按顺序排列,结束时间将不按顺序排列。

此外,您可能需要考虑将 aConcurrentHashMap用于多线程应用程序。


推荐阅读