多线程的处理方式
一般数据量比较大表 不可能一次性取出然后再对他修改 这样有很大的性能问题
可以通过多线程 父线程批量取出 子线程处理 子线程全部处理完成 父线程再去取
这样循环处理 好处在于 父线程可以控制子线程的数量也可以控制 批量取数的数量
下面是一个短信发送的例子
首先建立父线程也就是控制线程
package com.zte.ios.backprog.thread;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import com.zte.ios.basedata.business.intf.IosBuyInfoService;
import com.zte.ios.basedata.business.intf.IosGroupInfoService;
import com.zte.ios.basedata.business.intf.IosPersonInfoService;
import com.zte.ios.dto.business.bo.IosBuyInfoBO;
import com.zte.ios.dto.business.bo.IosGroupInfoBO;
import com.zte.ios.dto.business.bo.IosPersonInfoBO;
import com.zte.ios.dto.business.bo.IosPersonInfoExtBO;
import com.zte.ios.dto.business.bo.IosSMBlackAddrBO;
import com.zte.ios.dto.business.bo.IosSendConfigBO;
import com.zte.ios.dto.business.bo.IosSmSendBO;
import com.zte.ios.dto.business.specbo.IosSmSendQueryBO;
import com.zte.ios.frame.util.dateFormat.DateTimeFormat;
import com.zte.ios.smcenter.business.intf.IosSmBlackAddrService;
import com.zte.ios.smcenter.business.intf.IosSmSendService;
import com.zte.ios.sys.sendconfig.business.intf.IosSendConfigService;
import com.zte.ssb.framework.SSBBus;
/**
* 短信发送控制线程
* @author hezhenbo
*
*/
public class SMSSendControlThread extends Thread {
private IosSmSendService sendService = (IosSmSendService) SSBBus.findDomainService("iosSmSendDomainService");
private IosBuyInfoService buyInfoService= (IosBuyInfoService) SSBBus.findDomainService("iosBuyInfoService");
private IosPersonInfoService personInfoService = (IosPersonInfoService) SSBBus.findDomainService("iosPersonInfoService");
private IosGroupInfoService groupInfoService = (IosGroupInfoService) SSBBus.findDomainService("iosGroupInfoService");
private IosSendConfigService iosSendConfigService = (IosSendConfigService)SSBBus.findCommonService("iosSendConfigService");
private IosSmBlackAddrService iosSmBlackAddrService
= (IosSmBlackAddrService) SSBBus.findDomainService("iosSmBlackAddrService");
private List<IosSmSendBO> iosSmSendBoList;
//子线程数量
private int childCount = 0;
//一次获取的待发短信
private final int SEND_MAX_COUNT = 2000;
//一次启动的线程
private final int MAX_THREAD_COUNT = 30;
//待发状态
private final String WILL_SEND_STATUS = "3";
//停顿时间
private final int SLEEP_MILL_SECONDS = 10;
//是否停止主线程
private boolean stopFlag = true;
public void run() {
//Logger.getLogger(SMSSendControlThread.class).info("--启动发送短信控制线程" + (new java.util.Date()));
while(stopFlag)
{
iosSmSendBoList = getSmSendList(SEND_MAX_COUNT, WILL_SEND_STATUS,1);
if (iosSmSendBoList != null && iosSmSendBoList.size() > 0) {
for (int i = 0; i < iosSmSendBoList.size(); i++) {
IosSmSendBO smSendBO = iosSmSendBoList.get(i);
// 判断此短信是否已经设置为黑名单
if (smSendBO != null && !smSendBO.getStatus().equals("0"))
{
if (childCount < MAX_THREAD_COUNT) {
SMSSendThread sendThread = new SMSSendThread(smSendBO,this);
sendThread.setName("SendThread--"+ smSendBO.getOid() + "--" + i);
sendThread.start();
childCount++;
} else {
this.threadSleep(SLEEP_MILL_SECONDS);
}
}
}
iosSmSendBoList = null;
}
else
{
this.threadSleep(SLEEP_MILL_SECONDS);
}
while (childCount != 0)
{
this.threadSleep(SLEEP_MILL_SECONDS);
}
}
}
public synchronized void childThreadClose()
{
if (childCount > 0) {
childCount--;
}
}
@SuppressWarnings("unchecked")
private List<IosSmSendBO> getSmSendList(int maxCount,String status,int k)
{
List<IosSmSendBO> smSendBOList = null;
try
{
IosSmSendQueryBO queryBO = new IosSmSendQueryBO();
queryBO.getPageData().setPageNum(1);
queryBO.getPageData().setPageSize(maxCount);
queryBO.setStatus(status);
List<IosSendConfigBO> sendConfigslist = iosSendConfigService.getIosSendConfigs();
String sendQueueMethod = "";
if (sendConfigslist != null && sendConfigslist.size() > 0)
{
IosSendConfigBO bo = sendConfigslist.get(0);
sendQueueMethod = bo.getSendQueueMethod();
}
queryBO.setSendQueueMethod(sendQueueMethod);
//--end
smSendBOList = (List<IosSmSendBO>)sendService.getSendBoxList(queryBO);
IosSMBlackAddrBO query =null;
if (smSendBOList != null)
{
IosSmSendBO sendBO=null;
Set<String> personInfos=new HashSet<String>();
Map blackList=new HashMap();
Set buyList =new HashSet();
IosBuyInfoBO buyInfoBO=null;
for(int i=0;i<smSendBOList.size();i++)
{
sendBO = smSendBOList.get(i);
personInfos.add(sendBO.getCreatedBy());
query= new IosSMBlackAddrBO();
query.setSendTag("1");
query.setRecTag(null);
query.setGroupId(sendBO.getGroupId());
query.setMobileNo(sendBO.getReceiverCode());
blackList.put(sendBO.getOid(), query);
buyInfoBO = new IosBuyInfoBO();
buyInfoBO.setGroupId(sendBO.getGroupId());
buyList.add(buyInfoBO);
}
Map personInfoList = personInfoService.queryCorpLists(personInfos, false);
Map black=iosSmBlackAddrService.isBlackAddr(blackList);
Map buyLists=buyInfoService.getIosBuyInfoBOs(buyList);
for (int i = 0; i < smSendBOList.size(); i++)
{
sendBO = smSendBOList.get(i);
if(black.containsKey(sendBO.getOid()))
{
sendBO.setStatus("0");
// 失败原因
sendBO.setSendFailReason("号码:"
+ sendBO.getReceiverCode()
+ "是黑名单号码,禁止发送!");
Logger.getLogger(this.getClass()).info(
"号码:" + sendBO.getReceiverCode()
+ "是黑名单号码,禁止发送!");
// 发送时间
sendBO.setSendTime(DateTimeFormat.FormatDateToString(
new Date(), DateTimeFormat.DATE_WITH_TIME));
// 新增发送短信记录及在发送后修改后改变状态
sendService.updateIosSmSend(sendBO);
continue;
}
// 设置内外网号码
IosBuyInfoBO buyinfo = (IosBuyInfoBO)buyLists.get(sendBO.getGroupId());
sendBO.setExternalValueIn(buyinfo.getExternalValueIn());
sendBO.setExternalValueOut(buyinfo.getExternalValueOut());
//取出发送用户的信息
IosPersonInfoBO personInfo = (IosPersonInfoBO)personInfoList.get(sendBO.getCreatedBy());
if (personInfo != null ) {
//集团签名
String groupId = personInfo.getGroupId();
IosGroupInfoBO groupInfoBO = new IosGroupInfoBO();
groupInfoBO.setGroupId(groupId);
List<IosGroupInfoBO> groupInfoBOList = groupInfoService.getIosGroupInfoBOs(groupInfoBO);
if (groupInfoBOList != null && groupInfoBOList.size() > 0)
{
sendBO.setGroupName(groupInfoBOList.get(0).getGroupName());
//add by hezhenbo at 2009-06-13
sendBO.setBossId(groupInfoBOList.get(0).getBossId());
}
else
{
Logger.getLogger(SMSSendControlThread.class).error("groupId=" + groupId + "的集团为空。");
}
//是否加入集团签名
IosPersonInfoExtBO extBO = personInfo.getExtBo();
if (extBO != null)
{
if(extBO.getSendWithGroupName() != null && "1".equals(extBO.getSendWithGroupName()))
{
sendBO.setSendWithGroupName("1");
}
}
else
{
Logger.getLogger(SMSSendControlThread.class).error(
"获取用户扩展信息为空 userInfo.setOid ="
+ sendBO.getCreatedBy());
}
}
else
{
Logger.getLogger(SMSSendControlThread.class).error(
"获取用户信息为空 userInfo.setOid ="
+ sendBO.getCreatedBy());
}
}
}
}
catch(Exception e)
{
Logger.getLogger(SMSSendControlThread.class).error("获取待发列表异常", e);
}
return smSendBOList;
}
@SuppressWarnings("unchecked")
private List<IosSmSendBO> getSmSendList(int maxCount,String status)
{
List<IosSmSendBO> smSendBOList = null;
try
{
IosSmSendQueryBO queryBO = new IosSmSendQueryBO();
queryBO.getPageData().setPageNum(1);
queryBO.getPageData().setPageSize(maxCount);
queryBO.setStatus(status);
// add by ZouJing at 2009-6-9
List<IosSendConfigBO> sendConfigslist = iosSendConfigService.getIosSendConfigs();
String sendQueueMethod = "";
if (sendConfigslist != null && sendConfigslist.size() > 0)
{
IosSendConfigBO bo = sendConfigslist.get(0);
sendQueueMethod = bo.getSendQueueMethod();
}
queryBO.setSendQueueMethod(sendQueueMethod);
//--end
smSendBOList = (List<IosSmSendBO>)sendService.getSendBoxList(queryBO);
IosSMBlackAddrBO query = new IosSMBlackAddrBO();
query.setSendTag("1");
query.setRecTag(null);
if (smSendBOList != null)
{
for (int i = 0; i < smSendBOList.size(); i++)
{
IosSmSendBO sendBO = smSendBOList.get(i);
// add by ZouJing at Jun 17, 2009
// 操作黑名单短信
query.setGroupId(sendBO.getGroupId());
query.setMobileNo(sendBO.getReceiverCode());
if(iosSmBlackAddrService.isBlackAddr(query))
{
sendBO.setStatus("0");
// 失败原因
sendBO.setSendFailReason("号码:"
+ sendBO.getReceiverCode()
+ "是黑名单号码,禁止发送!");
Logger.getLogger(this.getClass()).info(
"号码:" + sendBO.getReceiverCode()
+ "是黑名单号码,禁止发送!");
// 发送时间
sendBO.setSendTime(DateTimeFormat.FormatDateToString(
new Date(), DateTimeFormat.DATE_WITH_TIME));
// 新增发送短信记录及在发送后修改后改变状态
sendService.updateIosSmSend(sendBO);
continue;
}
// 设置内外网号码
IosBuyInfoBO buyInfoBO = new IosBuyInfoBO();
buyInfoBO.setGroupId(sendBO.getGroupId());
List<IosBuyInfoBO> buyList = buyInfoService.getIosBuyInfoBOs(buyInfoBO);
sendBO.setExternalValueIn(buyList.get(0).getExternalValueIn());
sendBO.setExternalValueOut(buyList.get(0).getExternalValueOut());
//取出发送用户的信息
IosPersonInfoBO userInfo = new IosPersonInfoBO();
userInfo.setOid(sendBO.getCreatedBy());
List<IosPersonInfoBO> personInfoList = personInfoService.queryCorpLists(userInfo, false);
if (personInfoList != null && personInfoList.size() > 0) {
IosPersonInfoBO personInfo = personInfoList.get(0);
//集团签名
String groupId = personInfo.getGroupId();
IosGroupInfoBO groupInfoBO = new IosGroupInfoBO();
groupInfoBO.setGroupId(groupId);
List<IosGroupInfoBO> groupInfoBOList = groupInfoService.getIosGroupInfoBOs(groupInfoBO);
if (groupInfoBOList != null && groupInfoBOList.size() > 0)
{
sendBO.setGroupName(groupInfoBOList.get(0).getGroupName());
//add by hezhenbo at 2009-06-13
sendBO.setBossId(groupInfoBOList.get(0).getBossId());
}
else
{
Logger.getLogger(SMSSendControlThread.class).error("groupId=" + groupId + "的集团为空。");
}
//是否加入集团签名
IosPersonInfoExtBO extBO = personInfo.getExtBo();
if (extBO != null)
{
if(extBO.getSendWithGroupName() != null && "1".equals(extBO.getSendWithGroupName()))
{
sendBO.setSendWithGroupName("1");
}
}
else
{
Logger.getLogger(SMSSendControlThread.class).error(
"获取用户扩展信息为空 userInfo.setOid ="
+ sendBO.getCreatedBy());
}
}
else
{
Logger.getLogger(SMSSendControlThread.class).error(
"获取用户信息为空 userInfo.setOid ="
+ sendBO.getCreatedBy());
}
}
}
}
catch(Exception e)
{
Logger.getLogger(SMSSendControlThread.class).error("获取待发列表异常", e);
}
return smSendBOList;
}
private void threadSleep(int pauseTime)
{
try
{
Thread.sleep(pauseTime);
}
catch (InterruptedException e)
{
Logger.getLogger(SMSSendControlThread.class).error("threadSleep异常", e);
}
}
}
然后是子线程
package com.zte.ios.backprog.thread;
import java.util.Date;
import org.apache.log4j.Logger;
import com.zte.ios.asbadapter.business.adapter.IosSMSender;
import com.zte.ios.dto.business.bo.IosSmSendBO;
import com.zte.ios.dto.business.specbo.IosSmGeneralBO;
import com.zte.ios.frame.common.IosRet;
import com.zte.ios.frame.util.dateFormat.DateTimeFormat;
import com.zte.ios.smcenter.business.intf.IosSmSendService;
import com.zte.ssb.framework.SSBBus;
public class SMSSendThread extends Thread {
private IosSmSendBO smSendBO;
private final SMSSendControlThread fatherThread;
private IosSmSendService sendService = (IosSmSendService) SSBBus
.findDomainService("iosSmSendDomainService");
public void run() {
Logger.getLogger(SMSSendThread.class).info("发送短信--" + this.getName());
try {
IosSmGeneralBO iosSmGeneralBO = transferBO(smSendBO);
IosSMSender sender = new IosSMSender();
IosRet sendResult = sender.sendSM(iosSmGeneralBO);
String resulet = sendResult.getErrCode();
// 发送中,等待状态回复
if ("0".equals(resulet)) {
smSendBO.setStatus("1");
} else {
smSendBO.setStatus("0");
// 失败原因
smSendBO.setSendFailReason(sendResult.getErrMsg());
}
// 发送时间
smSendBO.setSendTime(DateTimeFormat.FormatDateToString(
new Date(), DateTimeFormat.DATE_WITH_TIME));
// 新增发送短信记录及在发送后修改后改变状态
sendService.updateIosSmSend(smSendBO);
} catch (Exception e) {
Logger.getLogger(SMSSendThread.class).error("线程发送短信异常", e);
} finally {
fatherThread.childThreadClose();
}
}
public SMSSendThread(IosSmSendBO smSendBO2,
SMSSendControlThread fatherThread2) {
this.smSendBO = smSendBO2;
this.fatherThread = fatherThread2;
}
/**
* BO转换方法
*/
private IosSmGeneralBO transferBO(IosSmSendBO sendBO) {
IosSmGeneralBO iosSmGeneralBO = new IosSmGeneralBO();
iosSmGeneralBO.setReceiveUserId("");
iosSmGeneralBO.setContent(sendBO.getContent());
iosSmGeneralBO.setCode(sendBO.getReceiverCode());
iosSmGeneralBO.setGroupId(sendBO.getGroupId());
// 设置oid,当不对数据库操作时sendBO的oid为空,则设任意值为0
if (sendBO.getOid() != null && !"".equals(sendBO.getOid())) {
iosSmGeneralBO.setExtInfo(sendBO.getOid());
} else {
iosSmGeneralBO.setExtInfo("0");
}
// add by hezhenbo at 2009-2-11
iosSmGeneralBO.setExternalValueIn(sendBO.getExternalValueIn());
iosSmGeneralBO.setExternalValueOut(sendBO.getExternalValueOut());
// add by hezhenbo at 2009-3-24
iosSmGeneralBO.setSendWithGroupName(sendBO.getSendWithGroupName());
iosSmGeneralBO.setGroupName(sendBO.getGroupName());
// add by hezhenbo at 2009-06-13
iosSmGeneralBO.setBossId(sendBO.getBossId());
return iosSmGeneralBO;
}
}