队列ArrayBlockingQueue的使用

这是一段生产者与消费者模式的队列线程:

package com.ceair.notify.scan.service;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import com.ceair.notify.config.service.ConfigService;
import com.ceair.notify.flight.entity.Flight;
import com.ceair.notify.flight.service.FlightService;

/**
* 系统启动后执行发不正常航班通知的任务
*/
public class JobInitBeanPostProcessor implements InitializingBean {
@Autowired
private FlightService flightService;
@Autowired
private FlightSendMessageService flightSendMessageService;
@Autowired
private ConfigService configService;

/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
BlockingQueue<Flight> flightQueue = new ArrayBlockingQueue<Flight>(5);
FlightProducer producer = new FlightProducer(flightQueue, flightService, configService);
FlightConsumer consumer = new FlightConsumer(flightQueue, flightSendMessageService);
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(producer);
pool.execute(consumer);
}


}

生产者:

package com.ceair.notify.scan.service;

import java.util.concurrent.BlockingQueue;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ceair.notify.config.service.ConfigService;
import com.ceair.notify.flight.entity.Flight;
import com.ceair.notify.flight.service.FlightService;

/**
* 航班选取,从航班缓冲池选取要发送通知的航班加入到发送队列
*/
public class FlightProducer implements Runnable {
private Log logger = LogFactory.getLog(getClass());
private BlockingQueue<Flight> flightQueue;
private FlightService flightService;
private ConfigService configService;

public FlightProducer(BlockingQueue<Flight> flightQueue, FlightService flightService, ConfigService configService) {
this.flightQueue = flightQueue;
//flightService = (FlightService)SystemBeanFactory.getBean("flightServiceImpl");
this.flightService = flightService;
this.configService = configService;
}

/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
while(true) {
//控制是否自动通知开关,YES自动通知
String isAutoNotify = configService.getIsAutoNotify();
if ("YES".equals(isAutoNotify)) {
addFlight();
}
}
}

private void addFlight() {
try {
Flight flight = flightService.doGetANotifyFlight();
if(flight != null) {
flightQueue.put(flight);
}
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}

}

消费者:

package com.ceair.notify.scan.service;

import java.util.concurrent.BlockingQueue;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ceair.notify.flight.entity.Flight;

/**
* 从航班发送队列里获取航班发送通知
*/
public class FlightConsumer implements Runnable {
private Log logger = LogFactory.getLog(getClass());
private BlockingQueue<Flight> flightQueue;
private FlightSendMessageService flightSendMessageService;

public FlightConsumer(BlockingQueue<Flight> flightQueue, FlightSendMessageService flightSendMessageService) {
this.flightQueue = flightQueue;
//flightSendMessageService = (FlightSendMessageService)SystemBeanFactory.getBean("flightSendMessageServiceImpl");
this.flightSendMessageService = flightSendMessageService;
}

/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
while(true) {
sendMessage();
}
}

private void sendMessage() {
Flight flight = null;
try {
flight = flightQueue.take();
flightSendMessageService.doSendMessage(flight);
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
}

}

}


遇到问题:
当消费者类FlightConsumer中的doSendMessage(flight)方法出现异常,外部获取不到异常内容,导致队列不能取,进而导致程序锁死。
原因:由于FlightConsumer类中的try{}catch(InterruptedException e){},一开始捕获异常用了InterruptedException,而非Exception,导致获取不到调用service方法中的异常信息,直接将最外的捕获异常改为Exception就行了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值