PEIYANGXINQU Ответов: 0

Как использовать concurrenthashmap в executorcompletionservice?


Я много раз искал в базе данных,даже у меня есть кэш какого-то результата, это все равно стоило очень много времени.
List<Map<Long, Node>> aNodeMapList = new ArrayList<>();
Map<String, List<Map<String, Object>>> cacheRingMap=new ConcurrentHashMap<>();
for (Ring startRing : startRings) {
       for (Ring endRing : endRings) {
           Map<String, Object> nodeMapResult = getNodeMapResult(startRing, endRing,cacheRingMap);
           Map<Long, Node> nodeMap = (Map<Long, Node>) nodeMapResult.get("nodeMap");
           if (nodeMap.size() > 0) {
               aNodeMapList.add(nodeMap);
           }
       }
   }

getNodeMapResult-это функция для поиска базы данных в соответствии с startRing, endRing и cache в cacheRingMap,и в следующий раз ей может не понадобиться искать базу данных,если я обнаружу, что результат существует в
cacheRingMap.

Что я уже пробовал:

Мой лидер сказал мне, что многопоточная технология может быть использована.Поэтому я меняю его на executorCompletionService,но теперь у меня есть
вопрос: является ли этот поток безопасным,когда я использую concurrentHashMap для кэширования результата в executorCompletionService?
Будет ли он работать быстро после того, как я изменюсь?
int totalThreadCount= startRings.size()*endRings.size();
ExecutorService threadPool2 =  Executors.newFixedThreadPool(totalThreadCount>4?4:2);
CompletionService<Map<String, Object>> completionService = new ExecutorCompletionService<Map<String, Object>>(threadPool2);
for (Ring startRing : startRings) {
        for (Ring endRing : endRings) {
            completionService.submit(new Callable<Map<String, Object>>() {
                    @Override
                    public Map<String, Object>  call() throws Exception {
                        return getNodeMapResult(startRing, endRing,cacheRingMap);
                    }
                });
        }
    }

    for(int i=0;i<totalThreadCount;i++){
    Map<String, Object> nodeMapResult=completionService.take().get();
    Map<Long, Node> nodeMap = (Map<Long, Node>) nodeMapResult.get("nodeMap");
    if (nodeMap.size() > 0) {
        aNodeMapList.add(nodeMap);
    }
    }

Catey Category

К сожалению, у меня нет решения для вас, но, возможно, я все еще могу помочь. То, что говорит вам ваш менеджер, потенциально верно. Многопоточный поиск по карте<t,k> может быть быстрее, если нет узких мест потока. Подумайте, например, о ключевых методах, которые синхронизируются. Они должны(если реализованы правильно) быть потокобезопасными, но не могут ускорить ваш поиск.

У меня была такая же проблема в движке рендеринга 2D-графики, где у меня были потоки, рендерингующие на один и тот же экран в своей собственной области экрана. Это может привести к более быстрому рендерингу, но метод построения ключа был синхронизирован, поэтому в конце концов все потоки ждали друг друга для построения графика. В конце концов, накладные расходы на управление потоками стоили больше времени, чем просто однопоточный растеризатор, который уже быстро работал.

Возможно, мой анекдот поможет вам проверить ваше решение на работоспособность.

0 Ответов