参考这个
https://blog.csdn.net/ZHJUNJUN93/article/details/78560700?utm_source=blogxgwz17
@Component
public class DealQueueThread implements Runnable {
private static DealQueueThread dealQueueThread;
@Autowired
BuyGoodService buyGoodService;
@Autowired
BuyOrdersService buyOrdersService;
@Autowired
JedisPool jedisPool;
private Jedis jedis;
private BuyQueue<BuyRequest> buyqueue;
public static boolean excute = false;//线程的默认执行标志为未执行,即空闲状态
public DealQueueThread() {
}
public DealQueueThread(BuyQueue<BuyRequest> buyqueue) {
this.buyqueue = buyqueue;
jedis = dealQueueThread.jedisPool.getResource();
}
@PostConstruct
public void init() {
dealQueueThread = this;
dealQueueThread.buyGoodService = this.buyGoodService;
dealQueueThread.buyOrdersService = this.buyOrdersService;
dealQueueThread.jedisPool = this.jedisPool;
}
@Override
public void run() {
try {
excute = true;//修改线程的默认执行标志为执行状态
//开始处理请求队列中的请求,按照队列的FIFO的规则,先处理先放入到队列中的请求
while (buyqueue != null && buyqueue.size() > 0) {
BuyRequest buyreq = buyqueue.take();//取出队列中的请求
dealWithQueue(buyreq);//处理请求
}
} catch (InterruptedException e) {
BaseLog.error("DealQueueThread:", e);
} finally {
excute = false;
}
}
public synchronized void dealWithQueue(BuyRequest buyreq) {
try {
//为了尽量确保数据的一致性,处理之前先从redis中获取当前抢购商品的剩余数量
int residue = Integer.valueOf(jedis.get("residue" + buyreq.getGood_id()));
if (residue < 1) {//如果没有剩余商品,就直接返回
buyreq.setResponse_status(3);
return;
}
//如果有剩余商品,先在redis中将剩余数量减一,再开始下订单
jedis.decr("residue" + buyreq.getGood_id());
//将数据库中将剩余数量减一,这一步处理可以在队列处理完成之后一次性更新剩余数量
dealQueueThread.buyGoodService.minusResidue(buyreq.getGood_id());
//处理请求,下订单
BuyOrders bo = new BuyOrders();
bo.setGood_id(buyreq.getGood_id());
bo.setUser_id(buyreq.getUser_id());
int order_id = dealQueueThread.buyOrdersService.insert(bo);
BuyOrders orders = dealQueueThread.buyOrdersService.getById(order_id);
buyreq.setOrder_id(order_id);//订单id
buyreq.setBuyOrders(orders);//订单信息
buyreq.setResponse_status(1);//处理完成状态
} catch (Exception e) {
buyreq.setResponse_status(2);//异常状态
BaseLog.error("DealQueueThread dealWithQueue:", e);
}
}
}
用的时候DealQueueThread dealQueue = new DealQueueThread(buyqueue);
从上面可见@Component,说明该类通过扫描,生成了bean,并且通过注入,将容器里的bean注入了进来,现在问题是这个类是个多线程处理,他用的时候是需要new的,不归spring管理,但是他通过一个静态数据成员 private static DealQueueThread dealQueueThread;把spring注入的bean又给保存起来了.
这个方法是挺好的,试用范围广,一般是你需要new的时候但是又想用spring的bean,比如activiti流程图的监听器.
否则就得自己在构造函数里,用spring工具类找到相应bean再赋值,相对麻烦点.
网友评论