队列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就行了

猜你喜欢

转载自chenxu-joy.iteye.com/blog/2262310
今日推荐