Java实现多线程的三种方式
Posted 路伟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java实现多线程的三种方式相关的知识,希望对你有一定的参考价值。
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 [email protected]<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 [email protected]<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 [email protected]<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 [email protected]<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 [email protected]<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 [email protected]<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 }
以上是关于Java实现多线程的三种方式的主要内容,如果未能解决你的问题,请参考以下文章