线程同步器机制有:
- 障栏;
- 倒计时门栓;
- 交换器;
- 同步队列;
- 信号量;
需求描述:
最近项目需要实现批量请求另外一个http协议的接口处理业务信息,并根据处理结果的返回值,更新系统业务状态。
鉴于系统高效性,摒弃逐个处理方式,采取多线程并发处理,提高系统效率。首先批量业务,逐个开启单独线程,建立http连接调用业务接口,但主进程循环开启线程后,需等待各个子线程处理完毕,并获取全部结果,根据相关结果进一步操作,因此需要线程同步器。
我选择使用倒计时门栓方法,实现以上需求。使用JAVA API的
代码:
1.自己扩展的线程同步辅助类,增加判断炒作是否失败的属性
import java.util.concurrent.CountDownLatch;
/**
* 线程同步辅助类
* @author jklot66
*
*/
public class OperCountDownLatch extends CountDownLatch {
public OperCountDownLatch(int arg0) {
super(arg0);
}
//判断是否存在处理失败
private boolean flag = true;
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
2.线程处理业务类
/**
* 线程处理业务类
* @author jklot66
*
*/
public class OperService implements Runnable {
//线程同步辅助类
private OperCountDownLatch operCountDownLatch;
private OperBean operBean;
public OperService(OperCountDownLatch operCountLatch,OperBean operBean){
this.operBean = operBean;
this.operCountDownLatch = operCountLatch;
}
//最大连接次数
private static Integer connectionTime = 3;
private static Logger logger = Logger.getLogger(OperService.class);
public void run(){
int replyOperTime = 0;
//递减锁存器的计数
operCountDownLatch.countDown();
doWork();
}
private void doWork(){
/**
some code */
}
}
3.主业务处理代码
public boolean oper(List<OperBean> listOper){
boolean result = false;
if( listOper != null && listOper.size() > 0 ){
//创建倒计时门栓
OperCountDownLatch operCountLatch = new OperCountDownLatch(listOper.size());
//创建线程执行器
Executor e = Executors.newCachedThreadPool();
for( int i = 0 ; i < listOper.size() ; i++ ){
OperBean operBean = listOper.get(i);
OperService operService = new OperService(operCountLatch,operBean);
e.execute(operFinshService);
}
//等待所有进程完成后继续执行,或者是等待超时后往下执行
operCountLatch.await(WAIT_MAX_TIME, TimeUnit.SECONDS);
if( operCountLatch.isFlag() ){
result = true;
}
}
return result;
}