昨天在做项目时,做了一个接口,接收数据并保存到数据库中,接收到的数据也会向memchched中保存,所以数据实际是以key和value的形式来传属的,而数据库中保存这些数据的时候,也会去判断是否有相同的key和存在,如果存在了,就会修改请求次数,而不回新增数据。
但是这样会有一个问题,当多并发访问接口时,就有可能导致会同时发送过来相同的数据,但这是同时在多个线程处理这些相同的数据,就会在数据的保存上出现错误。如何解决这个错误呢?
我是用了队列的方式,将所有的请求数据放到一个队列中,然后用一个线程去执行这个队列,顺序的把队列中的数据拿出来然后处理,这样就不回出现多个线程同时处理相同的数据的情况了,这种处理方式适合的那种多并发,然后数据之间还会有相互关联的情况。
public class QueueUtil {
private static Logger logger = Logger.getLogger(QueueUtil.class);
// 静态成员
private static final BlockingQueue<Blacklist> FILEQUEUE_FLOW = new ArrayBlockingQueue<Blacklist>(
10000);// 请求保存数据信息
/**
* 将请求保存数据放到队列中,一个一个保存
* @param blacklist
* @return
*/
public static boolean blacklistQueue(Blacklist blacklist) {
boolean flag = true;
if (!FILEQUEUE_FLOW.offer(blacklist)) {
logger.info("[ERROR.FILEQUEUE_FLOW fail!] " + blacklist);
flag = false;
}
return flag;
}
public static Blacklist pollFlow() {
if(FILEQUEUE_FLOW.isEmpty()){
return null;
}
return FILEQUEUE_FLOW.poll();
}
}
public class BlicklistThread extends Thread {
private static Logger logger = Logger.getLogger(BlicklistThread.class);
private BlacklistDao dao;
public BlicklistThread( BlacklistDao dao){
this.dao = dao;
}
@Override
public void run(){
while(true){
//读取队列
try{
//循环读取队列中的值并保存
Blacklist blacklist = QueueUtil.pollFlow();
while(blacklist != null ){
dao.saveOrUpdateBlacklist(blacklist);
blacklist = QueueUtil.pollFlow();
}
sleep(500);
} catch (Exception e) {
logger.error(e);
}
}
}
}