线程池的使用一

AdapterStartConfig

  • 项目一启动就执行,将自定义任务扔给线程池去跑
@Slf4j
@Component
public class AdapterStartConfig implements ApplicationListener<ContextRefreshedEvent> {

    @Resource
    LiveTvAdapter liveTvAdapter;

    /**
     * 线程池名称定义
     */
    private static final ThreadFactory POLLING_THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat("adapter-live-polling-%d").build();

    /**
     * 线程池
     */
    public static final ExecutorService ADAPTER_HANDLER_POOL = new ThreadPoolExecutor(1, 1, 0L,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(2048),
            POLLING_THREAD_FACTORY,
            new ThreadPoolExecutor.AbortPolicy());



    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        ADAPTER_HANDLER_POOL.execute(new Thread(liveTvAdapter));
    }
}

TvAdapter

  • 线程任务的模板,通过其他自定义类继承改类 实现自定义任务
@Slf4j
@Component
public abstract class TvAdapter implements Runnable
{

  /**
   * 线程休息时间,防止无任务执行,导致cpu性能过多消耗
   */
  public int  restTime = 5;

  /**
   * 是否当前有任务在跑的标识
   */
  public boolean  hasTaskRun = false;

  /**
   *  一次批量处理文件的个数
   */
  @Value("${adapter.live.ftp.batchFileSize}")
  public int batchFileSize = 10;

  /**
   * 获取批量文件
   */
  public abstract void fetchBatchFile();

  /**
   * 处理批量文件
   */
  public abstract void handleBatchFile();


  public  static   int  num = 0;
  @Override
  public void run()
  {
    boolean normal = true;
    while (true) {
      try {
        if (normal) {
            log.info("线程执行次数: {}", num++);
            long beginTime = System.currentTimeMillis();
            fetchBatchFile();
            handleBatchFile();
            long endTime = System.currentTimeMillis();
            log.info("当前线程总耗费时间(毫秒): {}", endTime - beginTime);
          }
        } catch (Exception e) {
          log.error("数据源处理出错:{}",e.getMessage());
          e.printStackTrace();
        }
        try {
          if (!hasTaskRun) {
            Thread.sleep(restTime * 1000);
          }
          normal = true;
        } catch (Exception e) {
          normal = false;
          log.error(e.getMessage());
          e.printStackTrace();
        }
    }
  }




}

LiveTvAdapter

  • 继承该以上任务父类类,实现自定义任务
@Component
@Slf4j
public class LiveTvAdapter extends TvAdapter {

	@Resource
	private MediaCmsPreChannelManage mediaCmsPreChannelManage;

	@Resource
	private MediaCmsPreScheduleBaseManage mediaCmsPreScheduleBaseManage;

	@Autowired
	ICmsPreChannelService cmsPreChannelService;

	/**
	 *  解析文档后信息           频道名称         目单信息
	 */
	public  ConcurrentHashMap<String, List<CmsPreScheduleBase>> channelProgramInfo = new ConcurrentHashMap<String, List<CmsPreScheduleBase>>(64);

	@Value("${adapter.live.ftp.host}")
	private String host;
	@Value("${adapter.live.ftp.port}")
	private int port;
	@Value("${adapter.live.ftp.username}")
	private String userName;
	@Value("${adapter.live.ftp.password}")
	private String passWord;
	@Value("${adapter.live.ftp.path}")
	private String ftpPath;
	@Value("${adapter.live.ftp.importPolicy}")
	private String importPolicy = "0";
	@Value("${adapter.live.ftp.localPath}")
	public String localPath;
	@Value("${adapter.live.ftp.fileCharset}")
	public String fileCharset;


	/**
	 * 节目单导入导出关键字
	 */
	private static final String WORD_CHANNEL = "Channel:";

	private static final String WORD_DATE = "Date:";


	/**
	 * 记录待处理的文件名称list
	 */
	public ArrayList<String> needHandle = new ArrayList<>();

	@Override
	public void fetchBatchFile() {
		// 根据ftp地址,账号,密码 获取tfp客户端
		// 根据ftp客户端获取指定目录
		// 根据目录下获取目录下面满足的文件
		// 将文件拷贝到本地创建的目录下,然后删除文件

		try {
			// 清除上一次冗余数据
			needHandle.clear();
			channelProgramInfo.clear();
			hasTaskRun = false;
			FtpConfig ftpConfig = new FtpConfig();
			ftpConfig.setFtpHost(host);
			ftpConfig.setFtpPort(port);
			ftpConfig.setFtpUserName(userName);
			ftpConfig.setFtpPwd(passWord);
			FtpUtil ftpUtil = new FtpUtil(ftpConfig);
			try {
				boolean isConnect = ftpUtil.connect();
				if (!isConnect) {
					log.info("ftp连接出现异常,请检查ftp服务!!!");
					return;
				}
			} catch (Exception e) {
				log.info("ftp连接出现异常,请检查ftp服务!!!");
				log.info(e.getMessage());
			}
			ftpUtil.downloadAndDelOriginalFile(ftpPath, ".ok", localPath, needHandle, batchFileSize);
			if (needHandle.size() > 0){
				hasTaskRun = true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void handleBatchFile() {
		long beginTime = System.currentTimeMillis();
		try {
			// 解析txt,每次获取本地目录下面的所有文件,
			if (needHandle.size() == 0) {
				return;
			}
			for (String fileName : needHandle) {
				// 解析txt文件,解析失败则继续处理后面的文件
				if (!parseTxt(fileName)) {
					continue;
				}
			}
			// 对节目单信息,字段进行补充,以及播出的时间和结束时间进行解析
			// 覆盖策略,直接删除,新增
			// 分割,根据播出时间和结束时间,分割成两个节目单
			Set<Map.Entry<String, List<CmsPreScheduleBase>>> entries = channelProgramInfo.entrySet();
			for (Map.Entry<String, List<CmsPreScheduleBase>> entry : entries) {
				String channelName = entry.getKey();
				CmsPreChannel channel = mediaCmsPreChannelManage.queryChannelByName(channelName);
				if (null == channel) {
					log.info("{}频道不存在,请进行频道的入库", channelName);
					continue;
				}
				List<CmsPreScheduleBase> list = entry.getValue();
				//   播出的时间(年月日)  当天的所有节目单
				Map<String, List<CmsPreScheduleBase>> map = list.stream().collect(Collectors.toMap(
						CmsPreScheduleBase::getPlayDate,
						a -> new ArrayList<>(Arrays.asList(a)),
						(a1, a2) -> {
							a1.addAll(a2);
							return a1;
						}));
				// 根据策略保存节目单
				for (Map.Entry<String, List<CmsPreScheduleBase>> programInfo : map.entrySet()) {
					String date = programInfo.getKey();
					List<CmsPreScheduleBase> programList = programInfo.getValue();
					if ("0".equals(importPolicy)) {
						mediaCmsPreScheduleBaseManage.injectionCoverUpdate(date, programList, channel);
					} else {
						mediaCmsPreScheduleBaseManage.injectionSplitUpdate(date, programList, channel);
					}
				}
			}
		} catch (Exception e) {
			log.info("节目单入库失败!!!");
			e.printStackTrace();
		}
		long endTime = System.currentTimeMillis();
		log.info("入库总耗费时间(毫秒): {}", endTime - beginTime);
	}


	/**
	 * 判断节目单是否跨天
	 *
	 * @param start
	 * @param end
	 * @return
	 */
	private boolean isCrossSky(String start, String end) {
		return NumberUtils.toInt(start) > NumberUtils.toInt(end);
	}

	/**
	 * 将节目单时间转成完整的日期
	 *
	 * @param time
	 * @param playDate
	 * @return
	 */
	private Date timeToDateTime(String time, String playDate) {
		return DateUtil.getDate(playDate + time, SHORT_DATE_FORMAT_YYYY_MM_DD_HH_SS);
	}


	/**
	 * 将数据保存到节目列表
	 *
	 * @param playDate
	 * @param arr
	 * @param list
	 */
	private void addScheduleToList(String playDate, String[] arr, List<CmsPreScheduleBase> list) {
		CmsPreScheduleBase schedule = new CmsPreScheduleBase();
		schedule.setPlayDate(playDate);
		schedule.setPlayStartDate(timeToDateTime(arr[0], playDate));
		schedule.setPlayEndDate(timeToDateTime(arr[1], playDate));
		schedule.setScheduleName(arr[2]);
		list.add(schedule);
	}


	/**
	 * 设置保存的节目单基本信息
	 *
	 * @param scheduleBase
	 * @param channel
	 */
	private void setScheduleInfo(CmsPreScheduleBase scheduleBase, CmsPreChannel channel) {
		String uuid = UUIDUtil.getUUID();
		scheduleBase.setCreateTime(new Date());
		scheduleBase.setChannelOutSourceId(channel.getOutSourceId());
		scheduleBase.setOutSourceId(uuid);
		scheduleBase.setInnerCode(uuid);
		scheduleBase.setCreateUser(JwtUtil.getUserName());
		scheduleBase.setCpCode(channel.getCpCode());
		scheduleBase.setDuration(DateUtils.getDurationByMinutes(scheduleBase.getPlayStartDate(), scheduleBase.getPlayEndDate()));
	}

	public boolean parseTxt(String fileName) {
		try {
			long beginTime = System.currentTimeMillis();
			String saveFilename = localPath + fileName;
			BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(saveFilename), fileCharset));
			String line = null;
			String playDate = "";
			String channelInfo = new String();
			List<CmsPreScheduleBase> list = new ArrayList<>();
			while ((line = reader.readLine()) != null) {
				if (line.trim().isEmpty()) {
					continue;
				}
				if (line.contains(WORD_CHANNEL)) {
					// 解析频道: 更新频道信息
					channelInfo = EditScheduleUtil.toScheduleDate(line);
					continue;
				} else if (line.contains(WORD_DATE)) {
					// 解析时间: 更新播出时间日期
					playDate = EditScheduleUtil.toScheduleDate(line);
				} else {
					// 解析节目单信息
					String[] arr = EditScheduleUtil.toScheduleData(line);
					// 判断是否跨天,跨天则拆分例如   1200-0100  拆分   1200-2359   0000-0100
					if (this.isCrossSky(arr[0], arr[1])) {
						this.addScheduleToList(playDate, new String[]{arr[0], "2359", arr[2]}, list);
						this.addScheduleToList(DateUtil.getAfterDateByOne(playDate),
								new String[]{"0000", arr[1], arr[2]}, list);
					} else {
						this.addScheduleToList(playDate, arr, list);
					}
				}
			}
			channelProgramInfo.put(channelInfo, list);
			long endTime = System.currentTimeMillis();
			log.info("文件解析总耗费时间(毫秒): {}", endTime - beginTime);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值