public Map<String, String> uploadMultiFile(List<MultipartFile> files){ if (null == files || files.size() == 0) { return new HashMap<>(); } try { Master master = new Master(ImWorker.class, files); if (master.isCompleted(30000)) { return getResult(master.getResultMap()); } } catch (Throwable e) { log.info("上传IM平台出现系统异常", e); throw new BizException("上传IM平台出现异常,稍后再试!"); } throw new BizException("上传入押单证超时!"); }
package com.paic.phucp.common.utils.master; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.paic.phucp.common.exception.BizException; import lombok.extern.slf4j.Slf4j; import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; @Slf4j public class Master { private ConcurrentHashMap<String,Object> resultMap = new ConcurrentHashMap<>(); private CountDownLatch count; private ExecutorService executorService; private final static int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2; private final static long KEEP_ALIVE_TIME = 10L; public ConcurrentHashMap<String, Object> getResultMap() { return resultMap; } public Boolean isCompleted (long timeout) { try { return count.await(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { log.info("上传文件超时!", e); Thread.currentThread().interrupt(); return false; } finally { executorService.shutdown(); } } public <T, E extends AbstractWorker> Master (Class<E> workerClass, List<T> objects) { Queue<Object> workerQueue = new ConcurrentLinkedQueue<>(objects); ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("ph-ucp-master-worker-%d").build(); executorService = new ThreadPoolExecutor(CORE_POOL_SIZE, CORE_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy()); count = new CountDownLatch(objects.size()); for (int i = 0; i < CORE_POOL_SIZE; i++) { try { E worker = workerClass.newInstance(); worker.setWorkerQueue(workerQueue); worker.setResultMap(resultMap); worker.setCount(count); executorService.submit(worker); } catch (Exception e) { log.info("创建Master线程池失败!", e); throw new BizException("通过反射创建worker实例失败:" + workerClass.getName()); } } } }
package com.paic.phucp.console.intergration.impl; import com.paic.phucp.common.constants.ImCoreConstants; import com.paic.phucp.common.cyberark.constants.PasswordKeyConstants; import com.paic.phucp.common.cyberark.pwd.PasswordUtil; import com.paic.phucp.common.utils.master.AbstractWorker; import com.pingan.cm.CMFileContentDTO; import com.pingan.cm.uploadclient.FileMatter; import com.pingan.cm.uploadclient.IMClient; import com.pingan.cm.uploadclient.IMClientFactory; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.web.multipart.MultipartFile; import java.util.Collections; import java.util.HashMap; @Slf4j public class ImWorker extends AbstractWorker { private static final String SEPARATOR = "."; @Override public Object handle(Object input) { try { MultipartFile file = (MultipartFile) input; String originalFilename = file.getOriginalFilename(); String fileName = StringUtils.substringBeforeLast(originalFilename, SEPARATOR); String type = StringUtils.substringAfterLast(originalFilename, SEPARATOR); final CMFileContentDTO fileContentDTO = new CMFileContentDTO(); fileContentDTO.setFileName(fileName); fileContentDTO.setMimeType(type); fileContentDTO.setBusinessType(ImCoreConstants.DEFAULT_BUSINESS_TYPE); FileMatter fileMatter = new FileMatter(); fileMatter.setFileContent(file.getBytes()); HashMap<String, String> mapInfo = new HashMap<>(); mapInfo.put(ImCoreConstants.PARAM_FILENAME, fileName); fileMatter.setMetaData(mapInfo); fileContentDTO.setFileList(Collections.singletonList(fileMatter)); IMClient imclient = IMClientFactory.getInstance().getIMClient(); String password = PasswordUtil.getPasswordByKey(PasswordKeyConstants.PHUCP_V_USER_PD); imclient.setPassword(password); String fileId = imclient.upload(fileContentDTO); log.info("IM上传文件fileId:" + fileId); return fileId; } catch (Exception e) { log.info("IM上传文件失败"); } return null; } @Override public void run() { while (true) { Object job = workerQueue.poll(); if (null == job) { break; } try { MultipartFile file = (MultipartFile) job; Object result = handle(job); resultMap.put(file.getOriginalFilename(), result); } finally { count.countDown(); } } } }
package com.paic.phucp.common.utils.master; import lombok.extern.slf4j.Slf4j; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; @Slf4j public abstract class AbstractWorker implements Runnable { protected Queue<Object> workerQueue = new ConcurrentLinkedQueue<>(); protected ConcurrentHashMap<String,Object> resultMap = new ConcurrentHashMap<>(); protected CountDownLatch count; void setWorkerQueue(Queue<Object> workerQueue) { this.workerQueue = workerQueue; } void setResultMap(ConcurrentHashMap<String, Object> resultMap) { this.resultMap = resultMap; } void setCount(CountDownLatch count) { this.count = count; } public abstract Object handle (Object input); }