生产者:往队列里塞入消息,实现消费者,多个生产者的产生和消费
public interface AcctBalcQueue {
void produce(Map<String, Object> objectsMap);
Map<String, Object> getData();
}
@Component("ABC_QUEUE")
public class ABCBalcQueue implements AcctBalcQueue {
// 日志记录器
private static final Logger logger = LogManager.getLogger();
// 消息队列,存储所有直连银行的交易明细信息
private final BlockingQueue<Map<String, Object>> basket = new LinkedBlockingQueue<Map<String, Object>>();
// 生产者,将银行交易明细放入队列
@Override
public void produce(Map<String, Object> objectsMap) {
// put方法放入一条交易明细,若basket满了,等到basket有位置
logger.info("ABC准备放入队列明细:" +objectsMap.toString());
try {
basket.put(objectsMap);
} catch(Exception e) {
logger.info("ABC准备放入队列明细报错:" +e);
}
logger.info("ABC放入队列明细结束:");
}
@Override
public Map<String, Object> getData() {
Map<String, Object> take = new HashMap<>();
try {
take = basket.take();
} catch (Exception e) {
logger.info("ABC取出队列明细报错:" +e);
}
return take;
}
}
@Component("BJBANK_QUEUE")
public class BJBANKBalcQueue implements AcctBalcQueue {
// 日志记录器
private static final Logger logger = LogManager.getLogger();
// 消息队列,存储所有直连银行的交易明细信息
private final BlockingQueue<Map<String, Object>> basket = new LinkedBlockingQueue<Map<String, Object>>();
// 生产者,将银行交易明细放入队列
@Override
public void produce(Map<String, Object> objectsMap) {
// put方法放入一条交易明细,若basket满了,等到basket有位置
logger.info("BJBANK准备放入队列明细:" +objectsMap.toString());
try {
basket.put(objectsMap);
} catch(Exception e) {
logger.info("BJBANK准备放入队列明细报错:" +e);
}
logger.info("BJBANK放入队列明细结束:");
}
@Override
public Map<String, Object> getData() {
Map<String, Object> take = new HashMap<>();
try {
take = basket.take();
} catch (Exception e) {
logger.info("BJBANK取出队列明细报错:" +e);
}
return take;
}
}
// 注入的方式
@Resource
Map<String, AcctBalcQueue> acctBalcQueues;
// <ABC_QUEUE, AcctBalcQueue>;<BJBANK_QUEUE, AcctBalcQueue>
// 写入的方式
Map<String, Object> mapsQueue = new HashMap<>();
acctBalcQueues.get(acctMntr.getBankTyp()+"_QUEUE").produce(mapsQueue);
消费的方式;采用实现线程的方式进行
@Component
public class ABCBalcQueueConsumer implements Runnable{
private static final Logger logger = LogManager.getLogger();
/*
*
*
* 17个队列消费者,只做更新和修改余额,余额发生变动时发送MQ
* */
@Autowired
private ABCBalcQueue abcBalcQueue;
@Autowired
private JobBankTaskExecService jobBankTaskExecService;
@Scheduled(fixedRate = 1000)
public void run() {
try {
// 消费
logger.info("拉回ABC余额队列消费者准备消费" );
while (true){
Map<String, Object> maps = abcBalcQueue.getData();
if (null != maps && maps.size()>0) {
jobBankTaskExecService.analysisBalcDueue(maps);
}
}
} catch (Exception ex) {
logger.error("拉回ABC余额队列消费者消费失败"+ex );
}
}
}
补充:存在线程资源的竞争,原因是@Scheduled是单线程,存在多个单线程会竞争资源
要设置一下配置
@Configuration
public class ScheduledTaskConfiguration implements SchedulingConfigurer {
private static final int FIVE = 20; // 多线程数
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(FIVE));
}
}