private static ThreadPoolExecutor service = new ThreadPoolExecutor(50, 200, 30L, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>()); private static ConcurrentHashMap<Long, Future<Zuji2YearCongratulationDto>> futures = new ConcurrentHashMap<Long, Future<Zuji2YearCongratulationDto>>(); @Override public Zuji2YearCongratulationDto getUserData(final long uid) { final int ttl = 20 * 60; final String key = "zuji2year:" + uid; //嘗試從緩存中取 Zuji2YearCongratulationDto dto = getZuji2YearCongratulationDtoFromCache(key); if (dto != null) { return dto; } LogDto logDto = new LogDto(); logDto.setPath("db"); logDto.setActiveThreadCountBefore(service.getActiveCount()); logDto.setQueueCountBefore(service.getQueue().size()); logDto.setCompleteCountBefore(service.getCompletedTaskCount()); logDto.setLargestPoolSizeBefore(service.getLargestPoolSize()); Future<Zuji2YearCongratulationDto> future = futures.get(uid); //判斷是否在隊列中 if (future == null) { //若是再也不隊列中,則加入取數據的隊列 future = service.submit(new Callable<Zuji2YearCongratulationDto>() { @Override public Zuji2YearCongratulationDto call() throws Exception { Zuji2YearCongratulationDto dto = getZuji2YearCongratulationDtoFromCache(key); if (dto == null) { dto = getZuji2YearCongratulationDto(uid); jedisTemplate.setex(key, new JsonSerializer().serialize(dto), ttl); } return dto; } }); futures.put(uid, future); } //加入隊列之後,每隔100ms判斷是否取到了數據,最多判斷100次,也就是最多等待10s int tryCount = 0; while (!future.isDone() && tryCount++ < 100) { try { Thread.sleep(100); } catch (InterruptedException e) { } } try { dto = future.get(1, TimeUnit.SECONDS); if (dto != null) { futures.remove(uid); } } catch (Exception e) { } logDto.setActiveThreadCountAfter(service.getActiveCount()); logDto.setQueueCountAfter(service.getQueue().size()); logDto.setCompleteCountAfter(service.getCompletedTaskCount()); logDto.setLargestPoolSizeAfter(service.getLargestPoolSize()); logDto.setEndTime(System.currentTimeMillis()); log.info(new JsonSerializer().serialize(logDto)); return dto; }