前言:
現(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");
}
}閑來無事,幫你寫了一個。
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");
}
}北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達內(nèi)教育集團成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進“中國制造2025”,實現(xiàn)中華民族偉大復(fù)興的升級產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。