BlockingQueue 可以是限定容量的。它在任意给定时间都可以有一个 remainingCapacity,超出此容量,便无法无阻塞地 put 附加元素。没有任何内部容量约束的 BlockingQueue 总是报告 Integer.MAX_VALUE 的剩余容量。
BlockingQueue 实现主要用于生产者-使用者队列,但它另外还支持 Collection 接口。因此,举例来说,使用 remove(x) 从队列中移除任意一个元素是有可能的。然而,这种操作通常不 会有效执行,只能有计划地偶尔使用,比如在取消排队信息时。
BlockingQueue 实现是线程安全的。所有排队方法都可以使用内部锁或其他形式的并发控制来自动达到它们的目的。然而,大量的 Collection 操作(addAll、containsAll、retainAll 和 removeAll)没有 必要自动执行,除非在实现中特别说明。因此,举例来说,在只添加了 c 中的一些元素后,addAll(c) 有可能失败(抛出一个异常)。
BlockingQueue 实质上不 支持使用任何一种“close”或“shutdown”操作来指示不再添加任何项。这种功能的需求和使用有依赖于实现的倾向。例如,一种常用的策略是:对于生产者,插入特殊的 end-of-stream 或 poison 对象,并根据使用者获取这些对象的时间来对它们进行解释。
需要说明的是,程序中的接口和DAO接口都是采用spring的ioc方式。
BlockingQueue 实现主要用于生产者-使用者队列,但它另外还支持 Collection 接口。因此,举例来说,使用 remove(x) 从队列中移除任意一个元素是有可能的。然而,这种操作通常不 会有效执行,只能有计划地偶尔使用,比如在取消排队信息时。
BlockingQueue 实现是线程安全的。所有排队方法都可以使用内部锁或其他形式的并发控制来自动达到它们的目的。然而,大量的 Collection 操作(addAll、containsAll、retainAll 和 removeAll)没有 必要自动执行,除非在实现中特别说明。因此,举例来说,在只添加了 c 中的一些元素后,addAll(c) 有可能失败(抛出一个异常)。
BlockingQueue 实质上不 支持使用任何一种“close”或“shutdown”操作来指示不再添加任何项。这种功能的需求和使用有依赖于实现的倾向。例如,一种常用的策略是:对于生产者,插入特殊的 end-of-stream 或 poison 对象,并根据使用者获取这些对象的时间来对它们进行解释。
下面就是在项目中使用BlockingQueue 具体是实现短信业务
发送短信队列类【SendMsgQueue.java】
/**
* SendMsgQueue.java
* 版权所有(C) 2012
* 创建:cuiran 2012-06-13 09:12:17
*/
package com.wpn.web.server.messageProcessor;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.wpn.cache.common.UserCallTaxiInfo;
import com.wpn.web.domain.mytmq.UserOrderInfo;
/**
* 发送短信队列
* @author cuiran
* @version TODO
*/
public class SendMsgQueue {
private static Log log = LogFactory.getLog(SendMsgQueue.class.getName());
private static int queueSize = 1000;
private static BlockingQueue<UserOrderInfo> queue = new ArrayBlockingQueue<UserOrderInfo>(queueSize);
public void setQueueSize(int queueSize) {
SendMsgQueue.queueSize = queueSize;
}
/**
* 取出用户购买订单信息
*
* @return
*/
public static UserOrderInfo getMessage() {
UserOrderInfo vo = null;
try {
vo = queue.take();
} catch (InterruptedException e) {
log.error("取出用户购买订单信息", e);
}
return vo;
}
/**
* 增加用户购买订单信息
*
* @param vo
*/
public static void putMessage(UserOrderInfo vo) {
try {
queue.put(vo);
} catch (InterruptedException e) {
log.error("增加用户购买订单信息", e);
}
}
}
对购买的信息发送短信提醒Handle处理类
/**
* SendMsgHandler.java
* 版权所有(C) 2012
* 创建:cuiran 2012-06-13 09:23:28
*/
package com.wpn.web.server.messageProcessor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.wpn.cache.common.UserCallTaxiInfo;
import com.wpn.web.dao.IGiftBaseInfoDao;
import com.wpn.web.dao.IUserBaseInfoDao;
import com.wpn.web.domain.mytmq.ParamCard;
import com.wpn.web.domain.mytmq.UserBaseInfo;
import com.wpn.web.domain.mytmq.UserOrderInfo;
import com.wpn.web.exception.DaoException;
import com.wpn.web.server.union.ISmsServer;
/**
* 处理发送用户购买套餐和礼品卡的短信提醒
* @author cuiran
* @version TODO
*/
public class SendMsgHandler implements Runnable {
private Log log = LogFactory.getLog(SendMsgHandler.class.getName());
private int id;
private ISmsServer sms;
private IUserBaseInfoDao userBaseInfoDao;
private IGiftBaseInfoDao giftBaseInfoDao;
@Override
public void run() {
Thread t = Thread.currentThread();
t.setName("handler-thread:" + id);
UserOrderInfo message=null;
while(true){
try{
message = SendMsgQueue.getMessage();
if (message == null) {
continue;
}
this.processorUserOrder(message);
}catch (Exception e) {
log.error("", e);
}
}
}
public SendMsgHandler(int id, ISmsServer sms,
IUserBaseInfoDao userBaseInfoDao,IGiftBaseInfoDao giftBaseInfoDao) {
super();
this.id = id;
this.sms = sms;
this.userBaseInfoDao = userBaseInfoDao;
this.giftBaseInfoDao=giftBaseInfoDao;
}
}
/**
* SendMsgService.java
* 版权所有(C) 2012
* 创建:cuiran 2012-06-13 09:28:34
*/
package com.wpn.web.server.messageProcessor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.wpn.web.dao.IGiftBaseInfoDao;
import com.wpn.web.dao.IUserBaseInfoDao;
import com.wpn.web.server.union.ISmsServer;
import com.wpn.web.util.HandlerThreadFactory;
/**
* 发送短信服务类
* @author cuiran
* @version TODO
*/
public class SendMsgService {
private Log log = LogFactory.getLog(SendMsgService.class.getName());
private int threadNumber = 2;
final ExecutorService exec = Executors.newFixedThreadPool(threadNumber,new HandlerThreadFactory());
private ISmsServer sms;
private IUserBaseInfoDao userBaseInfoDao;
private IGiftBaseInfoDao giftBaseInfoDao;
public void start() {
for(int i=0;i<threadNumber;i++){
exec.submit(new SendMsgHandler(i,sms,userBaseInfoDao, giftBaseInfoDao));
}
}
public void stop(){
exec.shutdown();
}
/**
* @return the sms
*/
public ISmsServer getSms() {
return sms;
}
/**
* @param sms the sms to set
*/
public void setSms(ISmsServer sms) {
this.sms = sms;
}
/**
* @return the userBaseInfoDao
*/
public IUserBaseInfoDao getUserBaseInfoDao() {
return userBaseInfoDao;
}
/**
* @param userBaseInfoDao the userBaseInfoDao to set
*/
public void setUserBaseInfoDao(IUserBaseInfoDao userBaseInfoDao) {
this.userBaseInfoDao = userBaseInfoDao;
}
/**
* @return the giftBaseInfoDao
*/
public IGiftBaseInfoDao getGiftBaseInfoDao() {
return giftBaseInfoDao;
}
/**
* @param giftBaseInfoDao the giftBaseInfoDao to set
*/
public void setGiftBaseInfoDao(IGiftBaseInfoDao giftBaseInfoDao) {
this.giftBaseInfoDao = giftBaseInfoDao;
}
}
需要说明的是,程序中的接口和DAO接口都是采用spring的ioc方式。