1、TicketQueue.java--队列封装类,负责如下职责:
a、把活动登记对象放入队列中
b、从队列中获取活动登记对象,并派券

package com.datong.pear.ticket;

import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.commons.lang.math.NumberUtils;
import org.apache.log4j.Logger; import com.datong.pear.system.common.Constants;
import com.datong.pear.system.common.Result; /**
* 活动登记队列
*
* @author jqlin
*/
public class TicketQueue {
private static ConcurrentLinkedQueue<ActivityRecordModel> linkedQueue = new ConcurrentLinkedQueue<ActivityRecordModel>(); private static final Logger logger = Logger.getLogger(TicketQueue.class); public static boolean isRunning = false; /**
* 活动登记对象放入队列中
*
* @param activityRecord
* @author jqlin
*/
public static void offer(ActivityRecordModel activityRecord) {
if(activityRecord == null){
logger.info(String.format("%s activityRecord is null", TicketQueue.class.getName()));
return;
} if(NumberUtils.toLong(activityRecord.getId(), 0) == 0L){
logger.info(String.format("%s activityRecord.id is illegal,activityRecord.id=%s",
TicketQueue.class.getName(), activityRecord.getId()));
return;
} logger.info(String.format("%s 即将放入队列的活动登记信息:%s", TicketQueue.class.getName(), activityRecord));
if(activityRecord.getState() != Constants.ActivityRecordStatus.WPF){
logger.info(String.format("%s activityRecordId=%s 状态不是未派发,无法放入队列", TicketQueue.class.getName(), activityRecord.getId()));
return;
} logger.info(String.format("%s activityRecordId=%s 准备放入队列", TicketQueue.class.getName(), activityRecord.getId()));
linkedQueue.offer(activityRecord);
logger.info(String.format("----setActivityRecordId=%s *****", activityRecord.getId()));
logger.info(String.format("%s activityRecordId=%s 放入队列成功", TicketQueue.class.getName(), activityRecord.getId()));
logger.info("**********************************************************************");
} /**
* 从队列中获取活动登记对象,并派券
*
* @return
* @author jqlin
*/
public static synchronized void pollAndSendTicket(TicketService ticketService) {
isRunning = true; logger.info("准备从队列中获取活动登记对象,并派券...");
if(linkedQueue != null && !linkedQueue.isEmpty()){
ActivityRecordModel activityRecordModel = null;
while (true) {
Iterator<ActivityRecordModel> arIterator = linkedQueue.iterator();
if(!arIterator.hasNext()){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
logger.info("队列派券异常中断");
} continue;
} activityRecordModel = arIterator.next();
logger.info(String.format("----getActivityRecordId=%s, Thread=%s *****", activityRecordModel.getId(), Thread.currentThread().getId()));
logger.info(String.format("%s 从队列中获取的活动登记信息:%s", TicketQueue.class.getName(), activityRecordModel)); logger.info(String.format("%s activityRecordId=%s 准备移出队列", TicketQueue.class.getName(), activityRecordModel.getId()));
linkedQueue.remove(activityRecordModel);
logger.info(String.format("%s activityRecordId=%s 移出队列成功", TicketQueue.class.getName(), activityRecordModel.getId())); logger.info(String.format("%s activityRecordId=%s 队列派券开始", TicketQueue.class.getName(), activityRecordModel.getId()));
Result result = ticketService.sendTicket(activityRecordModel);
logger.info(String.format("%s 活动登记派券接口返回信息:", TicketQueue.class.getName()));
logger.info(result);
logger.info(String.format("%s 活动登记派券结束", TicketQueue.class.getName())); logger.info("**********************************************************************");
}
} else {
logger.info("队列中活动登记对象为空,没有数据可派券...");
} isRunning = false;
}
}

2、启动线程执行队列

    /**
* 通过队列派券
*
* @param ar
* @param ticketService
* @author jqlin
*/
private synchronized void sendTicketByQueue(ActivityRecordModel ar, final TicketService ticketService) {
final ActivityRecordModel activityRecord = ar;
TicketQueue.offer(activityRecord);
//队列为空,启动一个线程
if(!TicketQueue.isRunning) {
new Thread(new Runnable(){
@Override
public void run() {
logger.info("启动一个线程,放入队列派券...");
TicketQueue.pollAndSendTicket(ticketService);
}
}).start(); }
}

队列送券的实际应用--ConcurrentLinkedQueue并发队列的更多相关文章

  1. 深入理解java:2.3.4. 并发编程concurrent包 之容器ConcurrentLinkedQueue(非阻塞的并发队列---循环CAS)

    1.    引言 在并发编程中我们有时候需要使用线程安全的队列. 如果我们要实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,另一种是使用非阻塞算法. 使用阻塞算法的队列可以用一个锁(入队和出 ...

  2. [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...

  3. 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  4. 阻塞队列LinkedBlockingQueue和并发队列ConcurrentLinkedQueue

    LinkedBlockingQueue: public class LinkedBlockingQueue<E> extends AbstractQueue<E> implem ...

  5. 并发队列之:BlockingQueue和ConcurrentLinkedQueue

    一.并行和并发区别: 并行:是指两者同时执行一件事.比如赛跑,两个人都在不停的往前跑: 并发:是指资源有限的情况下,两者交替轮流使用资源.比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给 ...

  6. 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法(转)

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  7. 并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别和使用场景总结

      三者区别与联系: 联系,三者 都是线程安全的.区别,就是 并发  和 阻塞,前者为并发队列,因为采用cas算法,所以能够高并发的处理:后2者采用锁机制,所以是阻塞的.注意点就是前者由于采用cas算 ...

  8. 并发队列ConcurrentLinkedQueue 和 阻塞队列LinkedBlockingQueue用法

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  9. 并发队列 ConcurrentLinkedQueue 及 BlockingQueue 接口实现的四种队列

    队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作.进行插入操作的端称为队尾,进行删除操作的端称为队头.队列中没有元素时,称为空队列. 在队列这 ...

随机推荐

  1. 【CentOS】安装RPM包或者源码包

    一.rpm  (是Redheat Package Manager的简称) 如果光驱中还有系统安装盘的话, 1.先挂载光驱, mount /dev/cdrom /mnt/ 2.cd /mnt/ 3.cd ...

  2. PHP函数、数组

    PHP函数 PHP的真正威力源自于它的函数函数是通过调用函数来执行的,可以在页面的任何位置调用函数 PHP函数准则:函数名称以字母或下划线开头(不能以数字开头)函数的名称应该提示出它的功能 四要素:返 ...

  3. 利用DelegatingHandler实现Web Api 的Api key校验

    客户端在请求Web Api时可以有以下两种方式提供API key 基于Querystring提供Api key http://localhost:57967/Api/Values?key=12345 ...

  4. 由overflow-x:scroll产生的收获

    我们都知道float:left属性会让元素向左浮动,如果用一个div将几个左浮动的li包起来,是不是div的宽度被li撑得很长很长呢,代码: <!DOCTYPE html> <htm ...

  5. [资源分享]yslow 与firebug 修复版本Firefox35【绿色版本下载】

    自从火狐也开始做版本帝后,相关查的插件越来越不好使了, 而且火狐集成自己的调试工具,也不是很好使用,Yslow 也坏掉了 找公司写c++修复了下 把yslow和Firebug 打包到一起,而且关闭自动 ...

  6. 使用maven搭建ssh框架

    首先搭建sturts2框架,配置pom文件: <properties> <!-- 文件拷贝时的编码 --> <project.build.sourceEncoding&g ...

  7. windows消息机制详解(转载)

    消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了.例如,单击鼠标.改变窗口尺寸.按下键盘上的一个键都会使Windows发送一个消息给应用程序.消息本身是作为一个记录传递给应用程序的 ...

  8. golang 裸写一个pool池控制协程的大小

    这几天深入的研究了一下golang 的协程,读了一个好文 http://mp.weixin.qq.com/s?__biz=MjM5OTcxMzE0MQ==&mid=2653369770& ...

  9. web前端笔试选择题

    1. 要动态改变层中内容可以使用的方法有(AB ) a)innerHTML b)innerText c)通过设置层的隐藏和显示来实现 d)通过设置层的样式属性的display属性 2. 当按键盘A时, ...

  10. 文档ID:某某 模板文件不存在,无法解析文档!

    如果是生成栏目列表时出现这样的问题]:   1.可以修改include/arc.listview.class.php这个文件. 2.复制代码     echo "模板文件不存在,无法解析文档 ...