多线程并行_countDown

/**
 * 首次启动加载数据至缓存
 */
public class ApplicationStartTask {

    private static Logger logger = LoggerFactory.getLogger(ApplicationStartTask.class);
    private AtomicInteger loadNum = new AtomicInteger(0);

    @Autowired
    private FaceProducer cacheSynchronizationProducer;
    @Autowired
    private FaceConsumer cacheSynchronizationConsumer;

    @Autowired
    private FaceInfoService faceInfoService;

    /**
     * 当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,
     * <br>等到需要执行的任务数大于线程池基本大小时就不再创建
     */
    private static final int POOL_CORE_SIZE = Runtime.getRuntime().availableProcessors();

    /**
     * 线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务
     */
    private static final int POOL_MAX_SIZE = Runtime.getRuntime().availableProcessors();

    /**
     * 线程池的工作线程空闲后,保持存活的时间 <br>
     * 单位:分
     */
    private static final int POOL_KEEP_ALIVE_TIME = 2;

    @Autowired
    @Qualifier("sqliteManagerImpl")
    private SqlieteManager sqlieteManager;

    @Autowired
    private FaceCompareManager faceCompareManager;

    @Value("${local.sqlite.sqlname}")
    private String sqlName;

    @Bean
    public ApplicationStartTask loadCache() {
        logger.info("[启动任务]首次启动载入数据至缓存...");
        checkSqLiteFile();
        List<String> belongIds = sqlieteManager.getAllBelongIds();
        if (ArrayUtil.isNotEmpty(belongIds)) {

            loadFromSqlite(belongIds);

            initMqServer();

            return new ApplicationStartTask();
        }
        loadFromDB();

        initMqServer();
        return new ApplicationStartTask();

    }

    /**
     * 开启MQ服务
     */
    private void initMqServer() {

        logger.info("开始开启MQ服务...");
        cacheSynchronizationProducer.producerStart();
        cacheSynchronizationConsumer.getMessage();
    }


    /**
     * 直接从MYSQL载入数据
     */
    private void loadFromDB() {
        logger.info("当前CPU内核线程数:{}", POOL_CORE_SIZE);

        long beginTimsamp = System.currentTimeMillis();

        List<String> allBelongId = faceCompareManager.getAllBelongId();
        int size = 0;
        for (String belongId : allBelongId) {
            FaceInfoSyncDataQuery query = new FaceInfoSyncDataQuery(belongId);
            query.setPageSize(1000);
            query.setDeleteStatus(0);
            Result<Integer> result = faceInfoService.getTotalPage(query);
            if (!result.isSuccess() || result.getModel() == 0) {
                continue;
            }

            int totalPage = result.getModel();

            size += totalPage;

        }
        logger.info("总任务数:{}", size);
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(POOL_CORE_SIZE, POOL_MAX_SIZE, POOL_KEEP_ALIVE_TIME,
                TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(size));
        CountDownLatch latch = new CountDownLatch(size);

        for (String belongId : allBelongId) {

            FaceInfoSyncDataQuery query = new FaceInfoSyncDataQuery();
            query.setBelongId(belongId);
            query.setDeleteStatus(0);
            query.setPageSize(1000);
            Result<FaceInfoSyncDataVO> result = faceInfoService.getFaces(query);
            if (!result.isSuccess() || result.getModel() == null || result.getModel().getTotalPages() == 0) {
                continue;
            }
            FaceInfoSyncDataVO faceInfoSyncDataVO = result.getModel();

            int totalPage = faceInfoSyncDataVO.getTotalPages();
            //第一页

            poolExecutor.execute(new CacheLoadTask1(1, belongId, faceInfoSyncDataVO.getFaces(), latch));
            if (totalPage == 1) {
                continue;
            }
            for (int i = 2; i <= totalPage; i++) {
                query = new FaceInfoSyncDataQuery();
                query.setBelongId(belongId);
                query.setPageSize(1000);
                query.setPageNo(i);
                query.setDeleteStatus(0);
                result = faceInfoService.getFaces(query);
                if (!result.isSuccess() || result.getModel() == null || ArrayUtil.isEmpty(result.getModel().getFaces())) {
                    continue;
                }
                faceInfoSyncDataVO = result.getModel();

                poolExecutor.execute(new CacheLoadTask1(i, belongId, faceInfoSyncDataVO.getFaces(), latch));


            }
        }
        try {

            latch.await();// 同步阻塞,直到所有线程工作完成
            // long endTime = System.currentTimeMillis(); // 获取结束时间

            poolExecutor.shutdown();// 不允许提交新任务,等待当前任务及队列中的任务全部执行完毕后退出
            // // 支持等待以前提交的任务停止执行
            // // 所有任务关闭请求或线程中断或超时,阻塞取消
            // poolExecutor.awaitTermination(20, TimeUnit.MINUTES);
            // poolExecutor.shutdownNow();//通过Thread.interrupt试图停止所有正在执行的线程,并不再处理还在队列中等待的任务...
        } catch (Exception e) {
            logger.error("[启动任务]线程池异常打印:{}", e);
            poolExecutor.shutdownNow();

        }
//        logger.info("[启动任务]从DB中载入数据至缓存完毕!共载入{}条人脸数据", loadNum.get());

        logger.info("[启动任务]完毕!全文索引{}条数据,共耗时:{}s", loadNum.get(), (System.currentTimeMillis() - beginTimsamp) / 1000);


    }

    class CacheLoadTask1 implements Runnable {


        private CountDownLatch latch;
        List<FaceInfoDO> faceInfoDOs = null;
        int putCacheNum = 0;
        String belongId = null;
        int pageNo = 0;

        public CacheLoadTask1(int pageNo, String belongId, List<FaceInfoDO> faceInfoDOs, CountDownLatch latch) {
            this.latch = latch;
            this.faceInfoDOs = faceInfoDOs;
            this.belongId = belongId;
            this.pageNo = pageNo;
            // this.index = index;
        }

        @Override
        public void run() {
            Long beginTime = System.currentTimeMillis();
            try {
                for (FaceInfoDO faceInfoDO : faceInfoDOs) {
                    boolean isPutCache = FaceInfoCacheManage.put(faceInfoDO);
                    if (isPutCache) {
                        putCacheNum++;
                        loadNum.incrementAndGet();

                    }
                }
                logger.info("[启动任务]线程{}处理完belongId-{}第{}页数据,共载入{}条人脸数据,耗时:{}ms", Thread.currentThread().getName(),
                        belongId, pageNo, putCacheNum, System.currentTimeMillis() - beginTime);

            } catch (Exception e) {
                logger.error("[启动任务]载入sqlite任务[CacheLoadTask]出错:{}", e);
            } finally {
                // TODO: handle finally clause
                latch.countDown();
            }
        }

    }

    /**
     * 从sqlite数据库中加载数据
     */
    private void loadFromSqlite(List<String> belongIds) {

        logger.info("当前CPU内核线程数:{}", POOL_CORE_SIZE);
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(POOL_CORE_SIZE, POOL_MAX_SIZE, POOL_KEEP_ALIVE_TIME,
                TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(belongIds.size()));
        CountDownLatch latch = new CountDownLatch(belongIds.size());
        for (String belongId : belongIds) {
            List<FaceInfoDO> faceInfoDOs = sqlieteManager.selectAllInfoByBelongId(sqlName, belongId);

            poolExecutor.execute(new CacheLoadTask(belongId, faceInfoDOs, latch));

        }

        try {

            latch.await();// 同步阻塞,直到所有线程工作完成
            // long endTime = System.currentTimeMillis(); // 获取结束时间
            logger.info("[启动任务]从sqlite中载入数据至缓存完毕!共载入{}条人脸数据", loadNum.get());

            poolExecutor.shutdown();// 不允许提交新任务,等待当前任务及队列中的任务全部执行完毕后退出
            // // 支持等待以前提交的任务停止执行
            // // 所有任务关闭请求或线程中断或超时,阻塞取消
            // poolExecutor.awaitTermination(20, TimeUnit.MINUTES);
            // poolExecutor.shutdownNow();//通过Thread.interrupt试图停止所有正在执行的线程,并不再处理还在队列中等待的任务...
        } catch (Exception e) {
            logger.error("[启动任务]线程池异常打印:{}", e);
            poolExecutor.shutdownNow();

        }

    }


    private void checkSqLiteFile() {
        File sqliteFile = new File(sqlName + ".sqlite3");
        if (!sqliteFile.exists()) {
            logger.info("[启动任务]sqlite数据库未创建,开始创建...");
            // 第一次启动创建本地表
            try {
                sqlieteManager.createTable(sqlName);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }

        }
    }

}

 



posted @ 2018-12-05 14:12  陶朱公Boy  阅读(464)  评论(0编辑  收藏  举报