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. ROS学习(二)—— 配置ROS环境

    一.管理环境 p { margin-bottom: 0.25cm; line-height: 120% } a:link { } 如果你在查找和使用ROS软件包方面遇到了问题,请确保你已经正确配置了脚 ...

  2. Tray - a SharedPreferences replacement for Android

    一个代替SharedPreferences的开源库, no Editor, no commit() no apply(),因此不存在UI卡顿现象,并且支持多线程,在一个线程中存另一个线程中取数据. h ...

  3. SQL SERVER 2005修改数据库名称,包括物理文件名和逻辑名称

    SQL SERVER 2005修改数据库名称,包括物理文件名和逻辑名称   原来数据库名称为 aa,物理文件名称为 aa.mdf 和 aa_log.ldf:   需要修改数据库名称为 bb,物理文件名 ...

  4. DirectX9 Sample_Empty Project

    作为第一个程序,EmpytProject仅仅示范了如何绑定DXUTstate结构中的回调函数. 回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当 ...

  5. PHPer不能不看的50个细节!

    1.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量, 单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的"函数&quo ...

  6. Redis 主从配置

    环境     Master/Slave     系统 IP Redis版本 Master     CentOS6.7         10.10.3.211         redis-3.2.6   ...

  7. Torch7学习笔记(三)Sequencialization

    1.序列化 Torch提供4种高级方法来序列化或者反序列化任意Lua/Torch对象.这些方法都是从File对象抽象出来的,为了方便操作而创建. 前两种方法用来从文件序列化或者反序列化的: torch ...

  8. Codeforces Round #384 (Div. 2) 734E Vladik and cards

    E. Vladik and cards time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. BFS/DFS算法介绍与实现(转)

    广度优先搜索(Breadth-First-Search)和深度优先搜索(Deep-First-Search)是搜索策略中最经常用到的两种方法,特别常用于图的搜索.其中有很多的算法都用到了这两种思想,比 ...

  10. post与get区别

    学习中,遇到get和post的提交方式,搜索整理了一下其区别: 关键词: PHP,Post,Get,区别 转载文章一: PHP中post与get的区别 Post 方法通过 HTTP post 机制,将 ...