多线程在项目中的引用(CountDownLatch)
Posted qingruihappy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程在项目中的引用(CountDownLatch)相关的知识,希望对你有一定的参考价值。
<bean id="exportThreadPoolExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="5" /> <property name="maxPoolSize" value="20" /> <property name="keepAliveSeconds" value="60" /> <property name="rejectedExecutionHandler"> <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </property> </bean>
package com.suning.dpms.biz.customer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import com.suning.dpms.dao.customer.CustDao; import com.suning.dpms.entity.HistoryCumulativeVO; import com.suning.dpms.intf.customer.ICustServicebiz; import com.suning.dpms.util.Constants; import com.suning.dpms.utils.AmountUtils; import com.suning.dpms.utils.DateUtil; import com.suning.dpms.vo.customer.DataAnalysisVO; import com.suning.dpms.vo.customer.TransactionStatisticsVO; import com.suning.dpms.vo.customer.UserFromResVO; import com.suning.dpms.vo.customer.UserFromVO; import com.suning.dpms.vo.customer.UserSummaryOverviewVO; import com.suning.dpms.vo.customer.UserSummaryTrendVO; import com.suning.dpms.vo.customer.UserSummaryVO; import com.suning.srccore.exception.BusinessException; import com.suning.srccore.vo.CoreRespCodeMsg; @Service public class CustServicebizImpl implements ICustServicebiz { private static final Logger logger = LoggerFactory.getLogger(CustServicebizImpl.class); @Autowired CustDao custDaobiz; @Resource(name = "exportThreadPoolExecutor") private ThreadPoolTaskExecutor exportThreadPoolExecutor; /** * pc端会员中心获取交易统计接口 */ @Override public TransactionStatisticsVO getTradeStatistics(String storeCode, String snCustNum) { Map<String, String> inParam = new HashMap<>(); inParam.put("storeCd", storeCode); inParam.put("snCustNum", snCustNum); String yesterday = DateUtil.getYesterday(); inParam.put("startDate", yesterday); TransactionStatisticsVO tradeStatistics = custDaobiz.getTradeStatistics(inParam); if (tradeStatistics == null) { tradeStatistics = new TransactionStatisticsVO(); tradeStatistics.setTotalTradingMoney("0"); tradeStatistics.setDeadline(DateUtil.formatDateStr2DateStr(yesterday)); tradeStatistics.setTotalTradingNum("0"); } tradeStatistics.setDeadline(DateUtil.formatDateStr2DateStr(tradeStatistics.getDeadline())); return tradeStatistics; } /** * 用户分析 * * @throws BusinessException */ @Override public DataAnalysisVO getDataAnalysis(String storeCode, final String dayType, final String trendType) throws BusinessException { // 入参设置 final Map<String, String> inParam = new HashMap<>(); String yesterday = DateUtil.getYesterday(); inParam.put("storeCd", storeCode); inParam.put("startDate", yesterday); final UserFromResVO[] resVO = new UserFromResVO[1]; final HistoryCumulativeVO[] historyCumulativeVO = new HistoryCumulativeVO[1]; final UserSummaryOverviewVO[] userSummaryOverviewVO = new UserSummaryOverviewVO[1]; final List<List<UserSummaryTrendVO>> dayUserSummaryTrendVOList = new ArrayList<>(); final CountDownLatch latch = new CountDownLatch(4); // 顾客来源分析 exportThreadPoolExecutor.execute(new Runnable() { @Override public void run() { try { resVO[0] = setUserFromVO(inParam); } catch (BusinessException e) { logger.error("会员中心CustServicebizImpl.setUserFromVO异常", e); } finally { latch.countDown(); } } }); // 历史累计 exportThreadPoolExecutor.execute(new Runnable() { @Override public void run() { try { historyCumulativeVO[0] = setHistoryCumulativeVO(inParam); } finally { latch.countDown(); } } }); // 设置顾客总览 exportThreadPoolExecutor.execute(new Runnable() { @Override public void run() { try { userSummaryOverviewVO[0] = setUserSummaryOverviewVO(dayType, inParam); } catch (BusinessException e) { logger.error("会员中心CustServicebizImpl.setUserSummaryOverviewVO异常", e); } finally { latch.countDown(); } } }); // 趋势分析 exportThreadPoolExecutor.execute(new Runnable() { @Override public void run() { try { dayUserSummaryTrendVOList.add(setDayUserSummaryTrendVO(dayType, trendType, inParam)); } catch (BusinessException e) { logger.error("会员中心CustServicebizImpl.setUserSummaryOverviewVO异常", e); } finally { latch.countDown(); } } }); try { latch.await(); } catch (Exception e) { logger.error("获取会员中心数据失败", e); } UserSummaryVO userSummaryVO = new UserSummaryVO(); userSummaryVO.setUserSummaryOverviewVO(userSummaryOverviewVO[0]); List<UserSummaryTrendVO> dayUserSummaryTrendVO = dayUserSummaryTrendVOList.isEmpty() ? null : dayUserSummaryTrendVOList.get(0); userSummaryVO.setUserSummaryTrendVOList(dayUserSummaryTrendVO); DataAnalysisVO dataAnalysisVO = new DataAnalysisVO(); dataAnalysisVO.setHistoryCumulativeVO(historyCumulativeVO[0]); dataAnalysisVO.setUserFromResVO(resVO[0]); dataAnalysisVO.setUserSummaryVO(userSummaryVO); return dataAnalysisVO; } /** * 历史累计 * * @param inParam * @return */ private HistoryCumulativeVO setHistoryCumulativeVO(Map<String, String> inParam) { HistoryCumulativeVO historyCumulativeVO = custDaobiz.getHistoryCumulativeVO(inParam); if (historyCumulativeVO != null) { historyCumulativeVO.setUserRepurchaseRate(AmountUtils.decimalToPercentage(historyCumulativeVO .getUserRepurchaseRate())); } else { historyCumulativeVO = new HistoryCumulativeVO(); } return historyCumulativeVO; } /** * 趋势分析 * * @param dayType * @param trendType * @param inParam * @return * @throws BusinessException */ private List<UserSummaryTrendVO> setDayUserSummaryTrendVO(String dayType, String trendType, Map<String, String> inParam) throws BusinessException { List<UserSummaryTrendVO> dayUserSummaryTrendVO = new ArrayList<>(); if (Constants.DayType.DAY.equalsIgnoreCase(dayType) || Constants.DayType.WEEK.equalsIgnoreCase(dayType)) { String endDate = DateUtil.getWeekDate(); inParam.put("endDate", endDate); if (Constants.TrendType.NEWUSERS.equalsIgnoreCase(trendType)) { dayUserSummaryTrendVO = custDaobiz.getUserSummaryTrendNewUsersVO(inParam); } else if (Constants.TrendType.NEWPAY.equalsIgnoreCase(trendType)) { dayUserSummaryTrendVO = custDaobiz.getUserSummaryTrendnewPayVO(inParam); } else if (Constants.TrendType.TOTALPAY.equalsIgnoreCase(trendType)) { dayUserSummaryTrendVO = custDaobiz.getUserSummaryTrendtotalPayVO(inParam); } else { logger.error("CustServicebizImpl.getDataAnalysis pc端传值trendType={}有误", trendType); throw new BusinessException(CoreRespCodeMsg.DAS_COMMON_0002.getCode(), CoreRespCodeMsg.DAS_COMMON_0002.getMsg()); } // 补齐7天 completionData(dayUserSummaryTrendVO, 7); } if (Constants.DayType.MOUTH.equalsIgnoreCase(dayType)) { String endDate = DateUtil.getMouthDate(); inParam.put("endDate", endDate); if (Constants.TrendType.NEWUSERS.equalsIgnoreCase(trendType)) { dayUserSummaryTrendVO = custDaobiz.getUserSummaryTrendNewUsersVO(inParam); } else if (Constants.TrendType.NEWPAY.equalsIgnoreCase(trendType)) { dayUserSummaryTrendVO = custDaobiz.getUserSummaryTrendnewPayVO(inParam); } else if (Constants.TrendType.TOTALPAY.equalsIgnoreCase(trendType)) { dayUserSummaryTrendVO = custDaobiz.getUserSummaryTrendtotalPayVO(inParam); } else { logger.error("CustServicebizImpl.getDataAnalysis pc端传值trendType={}有误", trendType); throw new BusinessException(CoreRespCodeMsg.DAS_COMMON_0002.getCode(), CoreRespCodeMsg.DAS_COMMON_0002.getMsg()); } // 补齐30天 completionData(dayUserSummaryTrendVO, 30); } return dayUserSummaryTrendVO; } /** * 补齐数据 */ public List<UserSummaryTrendVO> completionData(List<UserSummaryTrendVO> dayUserSummaryTrendVO, int date) { List<String> pastDate = DateUtil.getPastDate(date); // 如果没有查到数据直接全部补全 if (CollectionUtils.isEmpty(dayUserSummaryTrendVO)) { for (String time : pastDate) { UserSummaryTrendVO temp = new UserSummaryTrendVO(); temp.setxAxis(DateUtil.formatDateStr2DateStr(time)); temp.setyAxis("0"); dayUserSummaryTrendVO.add(temp); } listSort(dayUserSummaryTrendVO); return dayUserSummaryTrendVO; } // 如果查到数据,但数据不全,补全部分,并且要求转化时间格式 List<String> dbTimeList = new ArrayList<>(); for (UserSummaryTrendVO trendVO : dayUserSummaryTrendVO) { if (trendVO == null) { continue; } // 转化时间格式,下面两行有严格的顺序否则会出bug dbTimeList.add(trendVO.getxAxis()); trendVO.setxAxis(DateUtil.formatDateStr2DateStr(trendVO.getxAxis())); } for (String time : pastDate) { if (!dbTimeList.contains(time)) { UserSummaryTrendVO temp = new UserSummaryTrendVO(); temp.setxAxis(DateUtil.formatDateStr2DateStr(time)); temp.setyAxis("0"); dayUserSummaryTrendVO.add(temp); } } listSort(dayUserSummaryTrendVO); return dayUserSummaryTrendVO; } /** * 按照时间排序 * * @param list */ private void listSort(List<UserSummaryTrendVO> list) { Collections.sort(list, new Comparator<UserSummaryTrendVO>() { @Override public int compare(UserSummaryTrendVO o1, UserSummaryTrendVO o2) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); try { Date dt1 = format.parse(o1.getxAxis()); Date dt2 = format.parse(o2.getxAxis()); if (dt1.getTime() > dt2.getTime()) { return 1; } else if (dt1.getTime() < dt2.getTime()) { return -1; } else { return 0; } } catch (Exception e) { logger.error("会员中心时间对比排序出问题了:", e); } return 0; } }); } /** * 顾客总览 */ private UserSummaryOverviewVO setUserSummaryOverviewVO(String dayType, Map<String, String> inParam) throws BusinessException { UserSummaryOverviewVO userSummaryOverviewVO = null; if (Constants.DayType.DAY.equalsIgnoreCase(dayType)) { userSummaryOverviewVO = custDaobiz.getDayUserSummaryOverview(inParam); } else if (Constants.DayType.WEEK.equalsIgnoreCase(dayType)) { userSummaryOverviewVO = custDaobiz.getWeekUserSummaryOverview(inParam); } else if (Constants.DayType.MOUTH.equalsIgnoreCase(dayType)) { userSummaryOverviewVO = custDaobiz.getMouthUserSummaryOverview(inParam); } else { logger.error("CustServicebizImpl.getDataAnalysis 获取dayType={}有误", dayType); throw new BusinessException(CoreRespCodeMsg.DAS_COMMON_0002.getCode(), CoreRespCodeMsg.DAS_COMMON_0002.getMsg()); } // 新增顾客人数 if (userSummaryOverviewVO != null) { setUserSummaryOverviewVO(userSummaryOverviewVO); // 转换成百分比 userSummaryOverviewVO.setUserPreRepurchaseRate(AmountUtils.decimalToPercentage(userSummaryOverviewVO .getUserPreRepurchaseRate())); userSummaryOverviewVO.setUserRepurchaseRate(AmountUtils.decimalToPercentage(userSummaryOverviewVO .getUserRepurchaseRate())); } else { userSummaryOverviewVO = new UserSummaryOverviewVO(); } return userSummaryOverviewVO; } /** * 顾客来源设置 * * @return * @throws BusinessException */ private UserFromResVO setUserFromVO(Map<String, String> inParam) throws BusinessException { List<UserFromVO> userFromVO = custDaobiz.getUserFromVO(inParam); UserFromResVO resVO = new UserFromResVO(); if (!CollectionUtils.isEmpty(userFromVO)) { for (UserFromVO vo : userFromVO) { if (vo == null) { continue; } if (Constants.UserFromVO.STOREORDER.equals(vo.getCustomerSource())) { resVO.setStoreOrder(vo.getNewCustomers()); } else if (Constants.UserFromVO.NEWOPENS.equals(vo.getCustomerSource())) { resVO.setNewOpens(vo.getNewCustomers()); } else if (Constants.UserFromVO.SHOPPERSSTAMPS.equals(vo.getCustomerSource())) { resVO.setShoppersstamps(vo.getNewCustomers()); } else if (Constants.UserFromVO.SHOPORDER.equals(vo.getCustomerSource())) { resVO.setShopOrder(vo.getNewCustomers()); } else { logger.error("CustServicebizImpl.getDataAnalysis 获取customerSource={}有误,请大数据确认数据问题", vo.getCustomerSource()); throw new BusinessException(CoreRespCodeMsg.DAS_COMMON_0002.getCode(), CoreRespCodeMsg.DAS_COMMON_0002.getMsg()); } } } return resVO; } /** * 设置环比 * * @param userSummaryOverviewVO */ private void setUserSummaryOverviewVO(UserSummaryOverviewVO userSummaryOverviewVO) { // 上一周期新增顾客人数 String newPreUsersNum = userSummaryOverviewVO.getNewPreUsersNum(); // 新增顾客人数 String newUsersNum = userSummaryOverviewVO.getNewUsersNum(); // 获取百分比 String newUsersNumChain = AmountUtils.getPercentage(newPreUsersNum, newUsersNum); // 设置新增顾客环比 userSummaryOverviewVO.setNewUsersNumChain(newUsersNumChain); // 新增购买人数 String newPayUser = userSummaryOverviewVO.getNewPayUser(); // 上一周期新增购买人数 String newPrePayUser = userSummaryOverviewVO.getNewPrePayUser(); // 新增购买人数环比 String newPayUserChain = AmountUtils.getPercentage(newPrePayUser, newPayUser); // 新增购买人数环比 userSummaryOverviewVO.setNewPayUserChain(newPayUserChain); // 支付用户人数 String totalPayUser = userSummaryOverviewVO.getTotalPayUser(); // 上一周期支付用户人数 String newtotalPayUser = userSummaryOverviewVO.getNewtotalPayUser(); // 支付用户人数环比 String totalPayUserChain = AmountUtils.getPercentage(newtotalPayUser, totalPayUser); userSummaryOverviewVO.setTotalPayUserChain(totalPayUserChain); // 新增用户转换率 String userRepurchaseRate = userSummaryOverviewVO.getUserRepurchaseRate(); // 上一周期新增用户转换率 String userPreRepurchaseRate = userSummaryOverviewVO.getUserPreRepurchaseRate(); // 新增用户转换率环比 String userRepurchaseRateChain = AmountUtils .getPercentageSubtraction(userRepurchaseRate, userPreRepurchaseRate); userSummaryOverviewVO.setUserRepurchaseRateChain(userRepurchaseRateChain); } }
以上是关于多线程在项目中的引用(CountDownLatch)的主要内容,如果未能解决你的问题,请参考以下文章