博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Java实现多线程的三种方式

Posted on 2017-01-05 23:41  路伟  阅读(6111)  评论(0编辑  收藏  举报

  Java多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。前两种方式启动的线程没有返回值,启动后与主线程没有任何关系,主线程也不知道子线程是否执行结束;后一种方式线程有返回值,启动后主线程可以根据线程对象来判断显示是否结束以及获取线程执行结果,前者多用于,当执行一个主要任务时需要执行一个辅助耗时任务,但是主任务并不关心辅助任务是否执行成功,执行成功的结果是什么,后者多用于执行主任务时需要执行一个耗时的辅助任务,但是主任务的执行结果或者执行流向依赖于辅助任务的执行结果。

  1、继承Thread的方式实现线程

 1 package com.luwei.test.thread;
 2 
 3 public class ThreadMain {
 4 
 5     public static void main(String[] args) {
 6         System.out.println("主线程开始执行......");
 7         SubThread subThread = new SubThread();
 8         subThread.start();
 9         System.out.println("主线程执行结束......");
10     }
11 }
12 
13 class SubThread extends Thread {
14 
15     @Override
16     public void run() {
17         // 执行子线程业务逻辑
18         System.out.println("子线程启动开始执行子线程业务");
19     }
20 
21 }

  2、实现Runnable接口实现线程

 1 package com.luwei.test.thread;
 2 
 3 public class ThreadMain {
 4 
 5     public static void main(String[] args) {
 6         System.out.println("主线程开始执行......");
 7         SubThread subThread = new SubThread();
 8         Thread thread = new Thread(subThread);
 9         thread.start();
10         System.out.println("主线程执行结束......");
11     }
12 }
13 
14 class SubThread implements Runnable {
15 
16     @Override
17     public void run() {
18         // 执行子线程业务逻辑
19         System.out.println("子线程启动开始执行子线程业务");
20     }
21 
22 }

  3、实现Callable接口方式实现由返回值的线程

  1 package com.tinno.adsserver.biz;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Calendar;
  5 import java.util.Date;
  6 import java.util.HashMap;
  7 import java.util.List;
  8 import java.util.Map;
  9 import java.util.concurrent.Callable;
 10 import java.util.concurrent.ExecutionException;
 11 import java.util.concurrent.ExecutorService;
 12 import java.util.concurrent.Executors;
 13 import java.util.concurrent.Future;
 14 
 15 import javax.annotation.Resource;
 16 
 17 import org.slf4j.Logger;
 18 import org.slf4j.LoggerFactory;
 19 import org.springframework.stereotype.Service;
 20 
 21 import com.tinno.adsserver.base.BaseOutput;
 22 import com.tinno.adsserver.constants.EnumType.HoProtocol;
 23 import com.tinno.adsserver.constants.EnumType.HoRevenueType;
 24 import com.tinno.adsserver.constants.EnumType.HoStatus;
 25 import com.tinno.adsserver.constants.HoApiConst;
 26 import com.tinno.adsserver.constants.MainConst;
 27 import com.tinno.adsserver.constants.OutputCodeConst;
 28 import com.tinno.adsserver.model.ho.HoApiResult;
 29 import com.tinno.adsserver.model.ho.HoThreadBack;
 30 import com.tinno.adsserver.service.HoSyncService;
 31 import com.tinno.adsserver.utils.DateUtil;
 32 import com.tinno.adsserver.utils.HoApiUtil;
 33 import com.tinno.network.core.paging.QueryFilter;
 34 
 35 /**
 36  * <Description> HasOffer操作Biz<br>
 37  * 
 38  * @author lu.wei<br>
 39  * @email 1025742048@qq.com<br>
 40  * @date 2016年12月29日 <br>
 41  * @version 1.0<br>
 42  * @since V1.0<br>
 43  * @see com.tinno.adsserver.biz <br>
 44  */
 45 @Service("hasOfferOperateBiz")
 46 public class HasOfferOperateBiz {
 47     private Logger logger = LoggerFactory.getLogger(getClass());
 48 
 49     @Resource(name = "hoSyncService")
 50     private HoSyncService hoSyncService;
 51 
 52     public BaseOutput syncOfferToHasOffer(QueryFilter filter) throws InterruptedException, ExecutionException {
 53         BaseOutput out = new BaseOutput();
 54 
 55         Date now = new Date();
 56         long tm = now.getTime();
 57         int sum = 0;
 58         int addCnt = 0;
 59         int disableCnt = 0;
 60         int updateCnt = 0;
 61         int addFailCnt = 0;
 62         int disableFailCnt = 0;
 63         int updateFailCnt = 0;
 64         List<String> addFailIds = new ArrayList<String>();
 65         List<String> disableFailIds = new ArrayList<String>();
 66         List<String> updateFailIds = new ArrayList<String>();
 67 
 68         filter.getParam().put(MainConst.KEY_TM, String.valueOf(tm));
 69         // 为了防止长事务所表,将业务层的操作拆分出来
 70         // 1、进行预占数据
 71         int occupyCnt = hoSyncService.updateNotSyncOfferToOccupy(filter);
 72 
 73         // 2、获取占用数据
 74         List<Map<String, Object>> changedOffers = new ArrayList<Map<String, Object>>();
 75         if (occupyCnt > 0) {
 76             changedOffers = hoSyncService.selectFullOccupyChangeOffer(filter);
 77         }
 78 
 79         // 3、生成失效时间
 80         Calendar calendar = Calendar.getInstance();
 81         calendar.setTime(now);
 82         calendar.add(Calendar.YEAR, 1);
 83         Date yearDate = calendar.getTime();
 84         String expirDate = DateUtil.transferDateToStr(yearDate, DateUtil.DF_PATTERN_YYYY_MM_DD_HHMMSS);
 85         // 4、开始处理数据
 86         if (null != changedOffers && !changedOffers.isEmpty()) {
 87             sum = changedOffers.size();
 88             // 计算需要启动的线程数量
 89             // 每300条记录启动一个线程
 90             int threadCnt = (int) Math.ceil(sum / 300.0);
 91             ExecutorService pool = Executors.newFixedThreadPool(threadCnt);
 92             List<Future<HoThreadBack>> futures = new ArrayList<Future<HoThreadBack>>();
 93             for (int i = 0; i < threadCnt; i++) {
 94                 int startIndex = i * 300;
 95                 int endIndex = (i + 1) * 300;
 96                 if (endIndex > sum) {
 97                     endIndex = sum;
 98                 }
 99                 List<Map<String, Object>> subOfferData = changedOffers.subList(startIndex, endIndex);
100 
101                 Future<HoThreadBack> future = getDealSyncOfferFuture(pool, subOfferData, filter, expirDate);
102                 futures.add(future);
103             }
104 
105             int executeCnt = 0;
106             List<HoThreadBack> backs = new ArrayList<HoThreadBack>();
107             while (executeCnt < threadCnt) {
108                 List<Future<HoThreadBack>> forEachFutures = new ArrayList<Future<HoThreadBack>>();
109                 for (Future<HoThreadBack> future : futures) {
110                     if (future.isDone()) {
111                         backs.add(future.get());
112                         forEachFutures.add(future);
113                         executeCnt++;
114                     }
115                 }
116                 futures.removeAll(forEachFutures);
117             }
118             pool.shutdown();
119             if (!backs.isEmpty()) {
120                 for (HoThreadBack back : backs) {
121                     if (OutputCodeConst.SUCCESS.equals(back.getCode())) {
122                         addCnt += back.getAddCnt();
123                         updateCnt += back.getUpdateCnt();
124                         disableCnt += back.getDisableCnt();
125                         addFailCnt += back.getAddFailCnt();
126                         updateFailCnt += back.getUpdateFailCnt();
127                         disableFailCnt += back.getDisableFailCnt();
128 
129                         addFailIds.addAll(back.getAddFailIds());
130                         updateFailIds.addAll(back.getUpdateFailIds());
131                         disableFailIds.addAll(back.getDisableFailIds());
132                     }
133                     else {
134                         logger.error(back.getMsg());
135                     }
136                 }
137             }
138         }
139 
140         // 释放占用数据
141         int unOccupyCnt = hoSyncService.updateOccupyedOfferToReleased(filter);
142 
143         StringBuffer sb = new StringBuffer("");
144         sb.append("  执行同步Offer数据如下:  需要同步的数据总量为:").append(occupyCnt);
145         sb.append(";  能够同步的数据量为:").append(sum);
146         sb.append(";  新增成功的数据量为:").append(addCnt);
147         sb.append(";  更新成功的数据量为:").append(updateCnt);
148         sb.append(";  禁用成功的数据量为:").append(disableCnt);
149         sb.append(";  新增失败的数据量为:").append(addFailCnt);
150         sb.append(";  更新失败的数据量为:").append(updateFailCnt);
151         sb.append(";  禁用失败的数据量为:").append(disableFailCnt);
152         sb.append(";  释放的数据量为:").append(unOccupyCnt);
153         sb.append(";  新增失败的Offer为:").append(addFailIds);
154         sb.append(";  更新失败的Offer为:").append(updateFailIds);
155         sb.append(";  禁用失败的Offer为:").append(disableFailIds);
156         out.setMsg(out.getMsg() + sb.toString());
157 
158         return out;
159     }
160 
161     /**
162      * 
163      * <Description> 获取执行Future<br>
164      * 
165      * @author lu.wei<br>
166      * @email 1025742048@qq.com<br>
167      * @date 2016年12月29日 上午9:55:50
168      * @param threadPool
169      * @param offerDatas
170      * @param filter
171      * @param expirDate
172      * @return <br>
173      */
174     private Future<HoThreadBack> getDealSyncOfferFuture(ExecutorService threadPool, final List<Map<String, Object>> offerDatas,
175             final QueryFilter filter, final String expirDate) {
176         return threadPool.submit(new Callable<HoThreadBack>() {
177             @Override
178             public HoThreadBack call() throws Exception {
179                 return updateOfferToHO(offerDatas, filter, expirDate);
180             }
181         });
182     }
183 
184     /**
185      * 
186      * <Description> 同步Offer到HasOffers<br>
187      * 
188      * @author lu.wei<br>
189      * @email 1025742048@qq.com<br>
190      * @date 2016年12月29日 下午3:20:39
191      * @param offerDatas
192      * @param filter
193      * @param expirDate
194      * @return <br>
195      */
196     private HoThreadBack updateOfferToHO(List<Map<String, Object>> offerDatas, QueryFilter filter, String expirDate) {
197         String threadName = Thread.currentThread().getName();
198         HoThreadBack threadBack = new HoThreadBack();
199         int sum = offerDatas.size();
200         int addCnt = 0;
201         int disableCnt = 0;
202         int updateCnt = 0;
203         int addFailCnt = 0;
204         int disableFailCnt = 0;
205         int updateFailCnt = 0;
206         List<Map<String, String>> newHasOfferIds = new ArrayList<Map<String, String>>();
207         List<String> needUpdateIds = new ArrayList<String>();
208 
209         logger.info("-----------------------线程{}执行-------------------------------------Begin", threadName);
210 
211         BaseOutput out = new BaseOutput();
212         String hasOfferId = null;
213         int i = 1;
214         for (Map<String, Object> offerData : offerDatas) {
215             logger.info("线程 {} 总共需要执行的数据 {} 当前正在执行的是第{}个", threadName, sum, i);
216             String id = String.valueOf(offerData.get("id"));
217             filter.getParam().put("offerId", id);
218             Object hasofferIdObj = offerData.get("hasofferId");
219             // 执行新增操作
220             if (null == hasofferIdObj || "".equals(String.valueOf(hasofferIdObj))) {
221                 long begin = System.currentTimeMillis();
222                 // 稍后批量执行新增操作
223                 // hasOfferId = hoSyncService.addRemoteHoOffer(offerData,
224                 // expirDate);
225                 hasOfferId = addRemoateHoOffer(offerData, expirDate);
226                 logger.info("线程 {} 执行新增Offer({})到 HasOffer耗时{}", threadName, id, (System.currentTimeMillis() - begin));
227                 if (null != hasOfferId) {
228                     addCnt += 1;
229                     Map<String, String> idMap = new HashMap<String, String>();
230                     idMap.put(MainConst.KEY_ID, id);
231                     idMap.put(MainConst.KEY_CA_HASOFFERSOFFERID, hasOfferId);
232                     newHasOfferIds.add(idMap);
233                 }
234                 else {
235                     addFailCnt++;
236                     threadBack.getAddFailIds().add(id);
237                 }
238             }
239             // 执行更新操作
240             else {
241                 hasOfferId = String.valueOf(hasofferIdObj);
242                 String status = String.valueOf(offerData.get("status"));
243                 // 修改Offer为禁用状态
244                 if ("0".equals(status)) {
245                     out = updateRemoteHoOfferToDisabled(offerData);
246 
247                     if (out.getCode().equals(OutputCodeConst.SUCCESS)) {
248                         disableCnt += 1;
249                         needUpdateIds.add(id);
250                     }
251                     else {
252                         disableFailCnt++;
253                         threadBack.getDisableFailIds().add(id);
254                     }
255                 }
256                 // 执行更新目前只更新Offer Url
257                 else {
258                     out = updateRemoteHoOffer(offerData);
259                     if (out.getCode().equals(OutputCodeConst.SUCCESS)) {
260                         updateCnt += 1;
261                         needUpdateIds.add(id);
262                     }
263                     else {
264                         updateFailCnt++;
265                         threadBack.getUpdateFailIds().add(id);
266                     }
267                 }
268             }
269             i++;
270         }
271 
272         // 存在新增Offer
273         if (!newHasOfferIds.isEmpty()) {
274             filter.getExtraParam().put(MainConst.KEY_DATAS, newHasOfferIds);
275             hoSyncService.updateUnOfferdOfferToNotChange(filter);
276         }
277 
278         // 存在需要更新的Offer
279         if (!needUpdateIds.isEmpty()) {
280             filter.getExtraParam().put(MainConst.KEY_NEED_UPDATE_IDS, needUpdateIds);
281             hoSyncService.updateOfferdOfferToNotChange(filter);
282         }
283 
284         threadBack.setCode(out.getCode());
285         threadBack.setMsg(out.getMsg());
286         threadBack.setAddCnt(addCnt);
287         threadBack.setUpdateCnt(updateCnt);
288         threadBack.setDisableCnt(disableCnt);
289         threadBack.setAddFailCnt(addFailCnt);
290         threadBack.setDisableFailCnt(disableFailCnt);
291         threadBack.setUpdateFailCnt(updateFailCnt);
292 
293         logger.info(threadBack.toString());
294         logger.info("-----------------------线程{}执行-------------------------------------End", threadName);
295         return threadBack;
296     }
297 
298     /**
299      * 
300      * <Description> 将Offer新增到HasOffer<br>
301      * 
302      * @author lu.wei<br>
303      * @email 1025742048@qq.com<br>
304      * @date 2016年12月30日 下午2:09:52
305      * @param offerData
306      * @param expirDate
307      * @return <br>
308      */
309     private String addRemoateHoOffer(Map<String, Object> offerData, String expirDate) {
310         Object idObj = offerData.get("id");
311         logger.info("---------------addRemoteHoOffer({})-----------------------Begin", idObj);
312 
313         String hasOfferId = null;
314         try {
315             Map<String, Object> params = new HashMap<String, Object>();
316             params.put(HoApiConst.KEY_ADVERTISER_ID, String.valueOf(offerData.get("advertiserId")));
317             params.put(MainConst.KEY_NAME, String.valueOf(offerData.get(MainConst.KEY_NAME)));
318             if (null != offerData.get(MainConst.KEY_DESCRIPTION)) {
319                 params.put(MainConst.KEY_DESCRIPTION, String.valueOf(offerData.get(MainConst.KEY_DESCRIPTION)));
320             }
321             params.put(HoApiConst.KEY_PREVIEW_URL, String.valueOf(offerData.get("clickUrl")));
322             params.put(HoApiConst.KEY_OFFER_URL, String.valueOf(offerData.get("clickUrl")));
323             params.put(HoApiConst.KEY_STATUS, HoStatus.Active.getValue());
324             params.put(HoApiConst.KEY_EXPIRATION_DATE, expirDate);
325             params.put(MainConst.KEY_CURRENCY, String.valueOf(offerData.get(MainConst.KEY_CURRENCY)));
326             params.put(MainConst.KEY_PROTOCOL, HoProtocol.HttpiFramePixel.getValue());
327             logger.info(params.toString());
328             if (null != offerData.get("revenueType")) {
329                 String localRevenueType = String.valueOf(offerData.get("revenueType"));
330                 String revenueType = HoRevenueType.CPC.getValue();
331                 if ("cpi".equals(localRevenueType)) {
332                     revenueType = HoRevenueType.CPA_FLAT.getValue();
333                 }
334                 params.put(HoApiConst.KEY_REVENUE_TYPE, revenueType);
335             }
336             if (null != offerData.get("revenueRate")) {
337                 params.put(HoApiConst.KEY_MAX_PAYOUT, String.valueOf(offerData.get("revenueRate")));
338             }
339 
340             HoApiResult addResult = HoApiUtil.getHoOperateResult(HoApiConst.OFFER_CREATE_OFFER, params);
341             String status = addResult.getResponse().getStatus();
342             if (null != status && HoApiConst.KEY_STATUS_SUCCESS.equals(status)) {
343                 logger.info("HasOffers执行新增Offer成功!");
344                 Map<String, String> data = addResult.getResponse().getDatas().get(0);
345                 hasOfferId = data.get(MainConst.KEY_ID);
346             }
347             else {
348                 logger.error("执行HasOffer接口失败: {} ", addResult.getResponse().getErrorMessage());
349             }
350         }
351         catch (Exception e) {
352             logger.error("执行addRemoteHoOffer({})接口失败: {} ", idObj, e.getMessage(), e);
353         }
354         logger.info("---------------addRemoteHoOffer({})-----------------------End", idObj);
355         return hasOfferId;
356     }
357 
358     /**
359      * 
360      * <Description> 更新远程HasOffer信息<br>
361      * 
362      * @author lu.wei<br>
363      * @email 1025742048@qq.com<br>
364      * @date 2016年12月30日 下午2:24:14
365      * @param offerData
366      * @return <br>
367      */
368     private BaseOutput updateRemoteHoOffer(Map<String, Object> offerData) {
369         Object idObj = offerData.get("id");
370         logger.info("---------------updateRemoteHoOffer({})-----------------------Begin", idObj);
371         BaseOutput out = new BaseOutput();
372         try {
373             String hasOfferId = String.valueOf(offerData.get("hasofferId"));
374             Map<String, Object> dataParams = new HashMap<String, Object>();
375             dataParams.put(HoApiConst.KEY_ADVERTISER_ID, String.valueOf(offerData.get("advertiserId")));
376             dataParams.put(MainConst.KEY_NAME, String.valueOf(offerData.get(MainConst.KEY_NAME)));
377             if (null != offerData.get(MainConst.KEY_DESCRIPTION)) {
378                 dataParams.put(MainConst.KEY_DESCRIPTION, String.valueOf(offerData.get(MainConst.KEY_DESCRIPTION)));
379             }
380             dataParams.put(HoApiConst.KEY_PREVIEW_URL, String.valueOf(offerData.get("clickUrl")));
381             dataParams.put(HoApiConst.KEY_OFFER_URL, String.valueOf(offerData.get("clickUrl")));
382             dataParams.put(HoApiConst.KEY_STATUS, HoStatus.Active.getValue());
383             dataParams.put(MainConst.KEY_CURRENCY, String.valueOf(offerData.get(MainConst.KEY_CURRENCY)));
384             dataParams.put(MainConst.KEY_PROTOCOL, HoProtocol.HttpiFramePixel.getValue());
385 
386             if (null != offerData.get("revenueType")) {
387                 String localRevenueType = String.valueOf(offerData.get("revenueType"));
388                 String revenueType = HoRevenueType.CPC.getValue();
389                 if ("cpi".equals(localRevenueType)) {
390                     revenueType = HoRevenueType.CPA_FLAT.getValue();
391                 }
392                 dataParams.put(HoApiConst.KEY_REVENUE_TYPE, revenueType);
393             }
394             if (null != offerData.get("revenueRate")) {
395                 dataParams.put(HoApiConst.KEY_DEFAULT_PAYOUT, String.valueOf(offerData.get("revenueRate")));
396             }
397 
398             Map<String, String> urlParams = new HashMap<String, String>();
399             urlParams.put(MainConst.KEY_ID, hasOfferId);
400 
401             HoApiResult addResult = HoApiUtil.getHoOperateResult(HoApiConst.OFFER_UPDATE_OFFER, urlParams, dataParams);
402             String status = addResult.getResponse().getStatus();
403             if (null != status && HoApiConst.KEY_STATUS_SUCCESS.equals(status)) {
404                 logger.info("HasOffers执行修改Offer成功!");
405             }
406             else {
407                 out.setCode(OutputCodeConst.UNKNOWN_ERROR);
408                 out.setMsg("HasOffers执行修改Offer失败!");
409                 logger.error("执行updateRemoteHoOffer({})接口失败: {} ", idObj, addResult.getResponse().getErrorMessage());
410             }
411         }
412         catch (Exception e) {
413             out.setCode("-999");
414             out.setMsg("HasOffers执行修改Offer状态失败!");
415             logger.error("执行updateRemoteHoOffer({})接口失败: {} ", idObj, e.getMessage(), e);
416         }
417         logger.info("---------------updateRemoteHoOffer({})-----------------------End", idObj);
418         return out;
419     }
420 
421     /**
422      * 
423      * <Description> 禁用远程HasOffer<br>
424      * 
425      * @author lu.wei<br>
426      * @email 1025742048@qq.com<br>
427      * @date 2016年12月30日 下午2:26:54
428      * @param offerData
429      * @return <br>
430      */
431     private BaseOutput updateRemoteHoOfferToDisabled(Map<String, Object> offerData) {
432         Object idObj = offerData.get("id");
433         logger.info("---------------updateRemoteHoOfferToDisabled({})-----------------------Begin", idObj);
434 
435         BaseOutput out = new BaseOutput();
436         try {
437             String hasOfferId = String.valueOf(offerData.get("hasofferId"));
438 
439             Map<String, Object> dataParams = new HashMap<String, Object>();
440             dataParams.put(HoApiConst.KEY_STATUS, HoStatus.Expired.getValue());
441 
442             Map<String, String> urlParams = new HashMap<String, String>();
443             urlParams.put(MainConst.KEY_ID, hasOfferId);
444 
445             HoApiResult addResult = HoApiUtil.getHoOperateResult(HoApiConst.OFFER_UPDATE_OFFER, urlParams, dataParams);
446             String status = addResult.getResponse().getStatus();
447             if (null != status && HoApiConst.KEY_STATUS_SUCCESS.equals(status)) {
448                 logger.info("HasOffers执行修改Offer状态成功!");
449             }
450             else {
451                 out.setCode("-999");
452                 out.setMsg("HasOffers执行修改Offer状态失败!");
453                 logger.error("执行updateRemoteHoOfferToDisabled({})接口失败: {} ", idObj, addResult.getResponse().getErrorMessage());
454             }
455         }
456         catch (Exception e) {
457             out.setCode("-999");
458             out.setMsg("HasOffers执行修改Offer状态失败!");
459             logger.error("执行updateRemoteHoOfferToDisabled({})接口失败: {} ", idObj, e.getMessage(), e);
460         }
461         logger.info("---------------updateRemoteHoOfferToDisabled({})-----------------------End", idObj);
462         return out;
463     }
464 }

说明:

  在使用多线程的过成功为了减少类的开发经常会使用匿名内部类的方式来启动线程,这样减少线程类的开发,同时还可以让匿名内部类的访问外部类的内容,如下

 1 @RequestMapping("/add")
 2 @ResponseBody
 3 public String add(final HttpServletRequest request, HttpServletResponse response) {
 4     BaseOutput outPut = new BaseOutput();
 5     try {
 6         QueryFilter filter = new QueryFilter(request);
 7         logger.info(filter.toString());
 8         String country = filter.getParam().get(MainConst.KEY_COUNTRY);
 9         String email = filter.getParam().get(MainConst.KEY_EMAIL);
10         String zipcode = filter.getParam().get(MainConst.KEY_ZIPCODE);
11         if(!StringUtil.isEmpty(country) && !StringUtil.isEmpty(email) && !StringUtil.isEmpty(zipcode)) {
12             filter.getParam().clear();
13             filter.getParam().put(MainConst.KEY_EMAIL, email);
14             int cnt = advertiserService.getAdvertiserCnt(filter);
15             if(cnt == 0) {
16                 filter = new QueryFilter(request);
17                 outPut = advertiserService.add(filter);
18             } else {
19                 outPut.setCode(OutputCodeConst.EMAIL_IS_EXITS);
20                 outPut.setMsg(OutputCodeConst.getMsg(OutputCodeConst.EMAIL_IS_EXITS));
21             }
22         }
23         else {
24             outPut.setCode(OutputCodeConst.INPUT_PARAM_IS_NOT_FULL);
25             outPut.setMsg("Country and email and zipcode is needed.");
26         }
27     } catch (Exception e) {
28         logger.error("新增异常!", e);
29         outPut.setCode(OutputCodeConst.UNKNOWN_ERROR);
30         outPut.setMsg("新增异常! " + e.getMessage());
31     }
32     
33     //新增成功后同步
34     if(OutputCodeConst.SUCCESS.equals(outPut.getCode())) {
35         //新增后同步到HasOffer
36         String hsSyncSwitch = applicationConfiConst.getHsSyncSwitch();
37         if(null != hsSyncSwitch && HoApiConst.HS_SYNC_SWITCH_OPEN.equals(hsSyncSwitch)) {
38             //多线程方式进行处理
39             new Thread(new Runnable() {
40                 @Override
41                 public void run() {
42                     long begin = new Date().getTime();
43                     logger.info("新增同步开始, 开始时间: {} ", begin);
44                     try {
45                         QueryFilter filter = new QueryFilter(request);
46                         hasOfferOperateBiz.syncAdvertiserToHasOffer(filter);
47                     } catch(Exception e) {
48                         logger.error("新增同步广告商出错:{} ", e.getMessage(), e);
49                     }
50                     
51                     long end = new Date().getTime();
52                     logger.info("新增同步结束, 结束时间: {} ", end);
53                     logger.info("新增同步累计耗时: {} ", (end - begin));
54                 }
55             }).start();
56             
57         }
58     }
59     
60     return JsonUtil.objectToJson(outPut);
61 }
1 private Future<HoThreadBack> getDealSyncOfferFuture(ExecutorService threadPool, final List<Map<String, Object>> offerDatas,
2         final QueryFilter filter, final String expirDate) {
3     return threadPool.submit(new Callable<HoThreadBack>() {
4         @Override
5         public HoThreadBack call() throws Exception {
6             return updateOfferToHO(offerDatas, filter, expirDate);
7         }
8     });
9 }