在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Java/ 使用CountDownLatch解決程序性能問題

使用CountDownLatch解決程序性能問題

前言:

現(xiàn)在程序中有門店200個,每個門店對應(yīng)一個首頁。現(xiàn)在程序單線程執(zhí)行首頁靜態(tài)化耗費時間很長,約3小時。故此需要對它進行一番優(yōu)化。入行時間短暫,沒有并發(fā)編程的經(jīng)驗,所以在此請各位大大們能給出思路和經(jīng)驗,謝謝啦~

問題描述:
現(xiàn)有門店Id集合[List<Integer>],和執(zhí)行靜態(tài)化的方法[staticizeIndexBySubsite(Integer subId)],想開3個線程讓staticizeIndexBySubsite方法消費門店集合List,入行時間短暫加上工期緊急,沒有經(jīng)驗的我一時間想不到一種線程安全,不會跑重復(fù)的解決方案,所以只能上這里來求經(jīng)了 :)


代碼:

public synchronized void staticizeIndexBySubsites(List<Integer> subsiteIds) {
    if(CollectionUtils.isNotEmpty(subsiteIds)){
        for(Integer id : subsiteIds){
            //打算改成多線程處理的地方
            staticizeIndexBySubsite(id);
        }
    }
}


@Override
public void staticizeIndexBySubsite(Integer subsiteId) {
    if(NumberUtils.isEmpty(subsiteId)) return;
    try{
        Boolean ischinese;
        OverSeaHomeVO overSeaHomeVO;
        HomeNewVO homeNewVO;
        HomeNewVO wxHomeNewVO;
        String fileName;
        for(int y = 0 ; y<language.length;y++){
            ischinese = language[y];
            fileName = subsiteId+"-"+(language[y]==true?"zh-CN":"en")+".json";
            try {
                SubsiteDTO subsiteDTO = subSiteService.get(subsiteId);
                if(subsiteDTO != null && subsiteDTO.getStatus() == 1){
                    if(subsiteDTO.isIsGlobal()){//全球購
                        overSeaHomeVO = mobileStaticIndexService.getOverseaIndexBySubsite(subsiteId, ischinese, MultipleChannelsConstants.IOS_CHANNEL);
                        if(overSeaHomeVO != null){
                            writeAppIndex(successResult(overSeaHomeVO),parentRealPath,fileName);
                            writeAppIndex(successResult(overSeaHomeVO),wechatIndexReaPath,fileName);
                        }
                    }else{//普通站
                        homeNewVO = mobileStaticIndexService.getHomeNewBySubsite(MobileSiteStructureIdsConstant.MOBILE_NEW_SITE_STRUCTURE_ID_HOME, subsiteId, ischinese, MultipleChannelsConstants.IOS_CHANNEL);
                        if(homeNewVO != null){
                            writeAppIndex(successResult(homeNewVO),parentRealPath,fileName);
                        }
                        // 微信商城首頁
                        wxHomeNewVO = mobileStaticIndexService.getHomeNewBySubsite(MobileSiteStructureIdsConstant.MOBILE_SITE_STRUCTURE_ID_WX_HOME, subsiteId, ischinese, MultipleChannelsConstants.WEIXIN_CHANNEL);
                        if(wxHomeNewVO != null){
                            writeAppIndex(successResult(wxHomeNewVO),wechatIndexReaPath,fileName);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("MobileStaticIndexProcess error" + subsiteId+"***"+ischinese);
            }
        }
    }catch(Exception e){
        e.printStackTrace();
        log.error("手機端靜態(tài)化json有誤"+e.fillInStackTrace());
    }
}
回答
編輯回答
純妹

自問自答了....

final static int threadNum = 3; //線程數(shù)
static CountDownLatch countDownLatch = null;
@Override
public synchronized void staticizeIndexBySubsites(List<Integer> subsiteIds) throws Exception{
    if(CollectionUtils.isNotEmpty(subsiteIds)){
        countDownLatch = new CountDownLatch(threadNum);
        int length = subsiteIds.size();
        int tl = length % threadNum == 0 ? length / threadNum : (length/ threadNum + 1);
        for (int i = 0; i < threadNum; i++) {
            int end = (i + 1) * tl;
            HandleThread thread = new HandleThread(subsiteIds, i * tl, end > length ? length : end);
            thread.start();
        }
        countDownLatch.await();
    }
}

class HandleThread extends Thread {
    private List<Integer> data;
    private int start;
    private int end;
    public HandleThread(List<Integer> data, int start, int end) {
        this.data = data;
        this.start = start;
        this.end = end;
    }

    @Override
    public void run() {
        long startTime = System.currentTimeMillis();
        List<Integer> subList = data.subList(start, end);
        for(Integer item:subList){
            staticizeIndexBySubsite(item);
        }
        countDownLatch.countDown();
        System.out.println("線程:"+Thread.currentThread().getId()+"消費了"+subList.size()+"個分站,耗時:"+((System.currentTimeMillis() - startTime)/1000) + "s");
    }
}
2017年6月19日 19:43
編輯回答
落殤

閑來無事,幫你寫了一個。

public class Test0530 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        List<String> shops = new ArrayList<>();
        for (int i = 1; i <= 200; i++) {
            shops.add(i+"");
        }

        // 創(chuàng)建固定線程池 10個線程
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Future<String>> futures = new ArrayList<>();

        long start = System.currentTimeMillis();
        for (String shop : shops) {
            Future<String> future = executorService.submit(() -> {
                try {
                    // 模擬每次生成頁面需要5秒鐘
                    System.out.println("init " + shop);
                    Thread.sleep(5 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return shop;
            });
            futures.add(future);
        }
        
        for (Future<String> future : futures) {
            System.out.println("done " +future.get());
        }

        long end = System.currentTimeMillis();

        System.out.println("used time " + (end-start) + " ms");
    }
}
2017年10月26日 05:42