并发处理业务
来源:互联网 发布:有乎科技 编辑:程序博客网 时间:2024/05/14 09:43
最近有个任务,向200多万的用户分批发送msg 一周内完成。 这样的需求每天要发送几十万用户,用线程池并发处理,是再合适不过的。
研究了一下线程池, 用下面的代码,可以动态设定每天处理的数据量(分批处理)。 测试 100万左右数据 1个多小时,20万的数据10多分钟,基本达到需求。
有许多地方还在优化中
public class InviteCardThread extends Thread {
protected Logger logger = Logger.getLogger(InviteCardThread.class);
private Semaphore semaphore = new Semaphore(InviteCardUtil.semaphores);
private ToInviteBindCard sendMsg= null;
public InviteCardThread(ToInviteBindCard sendMsg,String name) {
// TODO Auto-generated constructor stub
super(name);
this.sendMsg = sendMsg;
}
public void run() {
try{
//申请线程
semaphore.acquire(InviteCardUtil.acquires);
// System.out.println("执行 "+getName());
// System.out.println(getName()+" 并行" + (Utile.semaphores-semaphore.availablePermits()) + "个机会,还有" + (semaphore.availablePermits()) + "个机会");
sendMsg.sendCard();
// 释放线程
semaphore.release();
// System.out.println("释放 "+getName());
}catch(Exception e){
e.printStackTrace();
}
}
}
public class ToInviteBindCard {
protected Logger logger = Logger.getLogger(ToInviteBindCard.class);
public static void main(String[] args) {
new ToInviteBindCard("20881034186580325271626702113553").sendCard();
}
public ToInviteBindCard(String userid) {
// this.userid = userid;
this.userid="20881034186580325271626702113553";
}
private String userid;
private int endflag=0;
public int getEndflag() {
return endflag;
}
/**
*
*/
public void sendCard() {
InviteUserInfo userinfo = new InviteUserInfo();
userinfo.setId(IdGen.uuid());
userinfo.setUser_id(userid);
//推广类型: 1绑卡邀请
userinfo.setPTYPE("1");
AlipayInviteMapper alipayInviteMapper = ContextLoader
.getCurrentWebApplicationContext().getBean(
AlipayInviteMapper.class);
try {
// 发送 邀请卡片
JSONObject jsonoCardbject = new ToAlipayServiceCardMsg()
.sendInviteCard(userid);
if (jsonoCardbject.getString("code").equals("200")) {
userinfo.setInvitebz("1");
} else {
userinfo.setInvitebz("0");
}
} catch (Exception e) {
e.printStackTrace();
userinfo.setInvitebz("0");
}finally{
//插入 已经发送过邀请的用户Id
alipayInviteMapper.insert(userinfo);
endflag=1;
}
}
}
public class InviteCardThreadPool {
protected Logger logger = Logger.getLogger(InviteCardThreadPool.class);
public static void main(String[] args) {
// 多次测试,取执行平均时间
InviteCardThreadPool main = new InviteCardThreadPool();
long total = 0;
for (int i = 0; i < InviteCardUtil.counter; i++) {
total = total + main.sendBindInvite();
}
System.out.println("cycle: "+InviteCardUtil.getCycle()+"; resources: " + InviteCardUtil.getResources() + "; semaphores:"
+ InviteCardUtil.semaphores + "; acquires: " + InviteCardUtil.acquires);
System.out.println("测试" + InviteCardUtil.counter + "次, 平均用时:" + InviteCardUtil.showNstoMs( total / InviteCardUtil.counter)
+ " ms");
}
public long sendBindInvite() {
long start = InviteCardUtil.getCurrentTimeMs();
long startns = InviteCardUtil.getCurrentTimeNs();
ExecutorService executorService = Executors.newCachedThreadPool();
Executors.newScheduledThreadPool(10);
try {
int c=0;
String user="";
int p=0;
List<ToInviteBindCard> objList = null;
// 分批执行
for (int j = 0; j < InviteCardUtil.getCycle(); j++) {
p=0;
List<String> tmp = new ArrayList<String>(InviteCardUtil.getResources());
objList = new ArrayList<ToInviteBindCard>(InviteCardUtil.getResources());
InviteUserInfo param = new InviteUserInfo();
param.setBegin(1);
param.setEnd(InviteCardUtil.getResources());
//获取这次 要发送的用户信息
AlipayInviteMapper alipayInviteMapper = ContextLoader.getCurrentWebApplicationContext().getBean(AlipayInviteMapper.class);
List<InviteUserInfo> info = alipayInviteMapper.getInviteUser(param);
//System.out.println("========================= cycle "+j+" : "+param.getBegin()+" : " +param.getEnd()+" : info.size="+info.size());
//全部发送完成,退出循环
if (info==null||info.size()==0){
break;
}
for (int i = 0; i < info.size(); i++) {
user = ((InviteUserInfo)info.get(i)).getUser_id();
if (user==null||"".equals(user.trim())||"null".equalsIgnoreCase(user.trim())){
continue;
}
tmp.add(user);
}
// System.out.println("========================= cycle "+j+" : tmp.size="+tmp.size());
//生成线程,并执行
for (String str : tmp) {
ToInviteBindCard toInviteBindCard = new ToInviteBindCard(str);
Thread thread = new InviteCardThread(toInviteBindCard, "job_"+c++);
executorService.execute(thread);
objList.add(toInviteBindCard);
}
// 所有线程全部执行完成
while (true){
p=0;
for (int n=0;n<objList.size(); n++){
p = p+ ((ToInviteBindCard)objList.get(n)).getEndflag();
}
if (p==objList.size()){
break;
}
}
}
logger.info("共处理 "+c+" 条数据");
// System.out.println("========================= 共处理 "+c+" 条数据");
} catch (Exception e) {
e.printStackTrace();
} finally {
executorService.shutdown();
long yong = InviteCardUtil.getTimeNs(startns);
// long yong = Utile.getTimeMs(start);
// System.out.println("第"+t+"次,used time is "+yong+" ns");
return yong;
}
}
- 并发处理业务
- 并发请求导致的业务处理安全风险及解决方案
- 并发请求导致的业务处理安全风险及解决方案
- 并发业务实例
- 并发处理
- 并发处理
- 并发处理
- 并发处理
- 并发处理
- 并发处理
- 处理并发
- 并发处理
- 系统定时处理业务
- PHP 业务错误处理
- 业务逻辑处理顺序
- FLEX业务处理
- 数据存储处理业务
- ADD业务处理逻辑
- centos you-dont-have-permission-to-access-phpmyadmin-on-this-server-in-centos7
- 差分约束系统
- Yii 两表如何通过中间表关联查询
- Linux的SOCKET编程详解
- 关于DNF的多媒体包NPK文件的那些事儿(1)
- 并发处理业务
- python 安装
- 练习1-8 编写一个统计空格、制表符与换行符个数的程序
- 两种方法获取select下拉框选中的option的值
- 5个数组Array方法: indexOf、filter、forEach、map、reduce使用实例
- Mysql 函数(个人收藏)
- iOS ffmpeg + libfdk-aac
- TabContainer要实现服务器端回传
- 解决问题了