Как использовать 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-графики, где у меня были потоки, рендерингующие на один и тот же экран в своей собственной области экрана. Это может привести к более быстрому рендерингу, но метод построения ключа был синхронизирован, поэтому в конце концов все потоки ждали друг друга для построения графика. В конце концов, накладные расходы на управление потоками стоили больше времени, чем просто однопоточный растеризатор, который уже быстро работал.
Возможно, мой анекдот поможет вам проверить ваше решение на работоспособность.