java异步队列

文章目录

  • 前言
  • 一、异步队列实现思路?
  • 二、实现步骤
    • 1.加入监听器
    • 2.实现监听器
    • 3.实现转交处理对象和转交处理线程
    • 4.自动转交异步处理
    • 5.业务如何添加


前言

在某些场景下,操作比较耗时,给用户体验不是很好,这时候我们就会直接想到两种方案,一种是定时任务,一种就是异步队列,那些实时性要求不高,且比较耗时的任务,是队列的最佳应用场景。


一、异步队列实现思路?

持久化=>插入队列=>出队,当程序突然停止,当程序启动的时候,从库里面拉出未执行的数据继续入队(补偿机制),下面是java的简单实现。

二、实现步骤

1.加入监听器

代码如下(示例):在web.xml 加入监听器

<!--转交异步处理监听器 --><listener><listener-class>context.ZjListener</listener-class></listener>

2.实现监听器

代码如下(示例):

public class ZjListener implements ServletContextListener {private static Logger log = LoggerFactory.getLogger(ZjListener.class);@Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {log.info("初始化转交异步处理线程...");ZjManager.getInstance().starup();log.info("初始化转交异步处理线程成功...");}@Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {ZjManager.getInstance().shutdown();}

3.实现转交处理对象和转交处理线程

代码如下(示例):我就简单示例一些,具体实现看业务昂

public class ZjRequset {private String dm;private String xh;public String getDm() {return dm;}public void setDm(String dm) {this.dm = dm;}public String getXh() {return xh;}public void setXh(String xh) {this.xh = xh;}
}
public class ZjThread implements Runnable{private ZjRequset requset;private ZjService zjService = WebAppContext.getBeanEx("ZjService");/*** @description 实例化一个自动转交处理线程* @param requset*/public ZjThread(ZjRequset requset){this.requset = requset;}/*** @description 获取请求* @return ZjRequset*/public ZjRequset getRequest() {return requset;}@Overridepublic void run() {if (requset != null){zjService.saveZj(requset.getDm(), requset.getXh());}}
}

4.自动转交异步处理

代码如下(示例):这一块就是核心的代码了

public class ZjManager {private static final Log LOG = LogFactory.getLog(ZjManager.class);private static final ZjManager INSTANCE = new ZjManager();/*** 线程池维护线程的最少数量*/private final static int CORE_POOL_SIZE = 2;/*** 线程池维护线程的最大数量*/private final static int MAX_POOL_SIZE = 3;/*** 线程池维护线程所允许的空闲时间*/private final static int KEEP_ALIVE_TIME = 0;/*** 线程池所使用的缓冲队列大小*/private final static int WORK_QUEUE_SIZE = 200;/*** 是不是第一次启动程序*/private static boolean FIRST_QD = true;/*** 自动转交异步处理队列*/private final Queue<ZjRequset> requestQueue = new LinkedList<ZjRequset>();/*** 线程池*/private ThreadPoolExecutor threadPool = null;/*** 调度器*/private ScheduledExecutorService scheduler = null;/*** @description 获取异步处理管理器实例*/public static ZjManager getInstance(){return INSTANCE;}/*** @description 队列是否为空*/private boolean hasAcquire() {return !requestQueue.isEmpty();}/*** @description 启动工作线程*/public boolean starup(){LOG.info( Console.getNowStr() + " 正在启动异步处理管理器...");threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(WORK_QUEUE_SIZE), this.handler);scheduler = Executors.newScheduledThreadPool(1);scheduler.scheduleAtFixedRate(accessBufferThread, 0, 3, TimeUnit.SECONDS);LOG.info(Console.getNowStr() + " 启动异步处理管理器成功!");return true;}/*** @description 关闭工作线程*/public void shutdown(){if (scheduler != null) {scheduler.shutdown();}if (threadPool != null) {threadPool.shutdown();}}/*** @description 处理器*/final RejectedExecutionHandler handler = new RejectedExecutionHandler() {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {synchronized (requestQueue) {try {requestQueue.offer(((ZjThread) r).getRequest());} catch (Exception e) {LOG.error("插入自动转交队列失败",e);}}}};/*** @description 访问消息缓存的调度线程,查看是否有待定请求,如果有,则创建一个新的,并添加到线程池*/final Runnable accessBufferThread = new Runnable() {@Overridepublic void run() {synchronized (requestQueue) {try {if (FIRST_QD){reloadRequest();}if (hasAcquire()) {ZjRequset request = requestQueue.poll();if (request != null) {Runnable task = new ZjThread(request);threadPool.execute(task);}}} catch (Exception e) {LOG.error("重新执行失败",e);}}}};/*** 增加一个数据库操作** @param request the request*/public void AddRequest(ZjRequset request) {try {if (request != null) {//持久化,写入库中wirteRequest(request);Runnable task = new ZjThread(request);threadPool.execute(task);}} catch (Exception e) {LOG.error(e.getMessage(),e);}}/*** 写入到表中** @param request the request*/void wirteRequest(ZjRequset request) {//将要请求写入库}/*** 将库中未执行的任务添加到队列中*/void reloadRequest() {FIRST_QD = false;Connection conn = null;PreparedStatement pst = null;ResultSet rs = null;//举个例子try {conn = getConn();pst = conn.prepareStatement(sql);rs = pst.executeQuery();while (rs.next()) {ZjRequset request = new ZjRequset();request.setDm(rs.getString("DM"));request.setXh(rs.getString("XH"));ZjManager.getInstance().AddRequest(request,"");}} catch (SQLException e) {LOG.error(e.getMessage(), e);}finally {DBUtils.closeResultSet(rs);DBUtils.closePStatement(pst);DBUtils.closeConnection(conn);}}/*** 获取队列待处理线程数量*/public int getQueueCount(){return requestQueue.size();}/*** 获取处理线程的状态*/public int getThreadZt(){return threadPool.getActiveCount();}}

5.业务如何添加

			ZjRequset clRequest = new ZjRequset();clRequest.setDm(dm);clRequest.setXh(xh);ZjManager.getInstance().AddRequest(clRequest);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/355073.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python27怎么使用_pygtk:glade的使用(针对python27的第一个例子)

glade是一个用来创建GTK界面的软件&#xff0c;这个界面以xml形式表示。这样达到了界面与语言分离的效果&#xff0c;pygtk就能使用这种方法来快速构建界面。在知道这个以前&#xff0c;我一直都是一个一个字母的敲出来的界面&#xff0c;实在无法忍受已经准备投入pyqt怀抱的时…

Kali 2017更新源

一、添加更新源 leafpad /etc/apt/sources.list 二、国内更新源 #autodeb http://http.kali.org/kali kali-rolling main non-free contrib#中科大 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib deb-src http://mirrors.ustc.edu.cn/kali kali-rol…

获取hh:mm:ss

获取hh:mm:ss format(date, "HH:mm:ss")

orm的理解_ORM仇恨者无法理解

orm的理解我看过无数的文章和评论&#xff08;尤其是评论&#xff09;&#xff0c;它们告诉我们ORM&#xff08;对象关系映射&#xff09;概念的严重性&#xff0c;糟糕性和错误性。 以下是通常的声明&#xff0c;以及我对它们的评论&#xff1a; “它们很慢” –映射有一些开销…

华为手机打字声音怎么开启_华为手机这5个超实用小功能,记得要开启,谁用都说好...

华为手机这5个超实用小功能&#xff0c;记得要开启&#xff0c;谁用都说好用过华为手机的用户应该都知道&#xff0c;emui优化的很到位&#xff0c;同时也给用户非常好的体验感&#xff0c;随着系统的优化&#xff0c;功能也是越来越完善&#xff0c;不仅越来越好用&#xff0c…

ORM进阶之Hibernate 的三大对象

ORM进阶之 ORM简单介绍 ORM进阶之Hibernate 简单介绍及框架搭 ORM进阶之Hibernate 的三大对象 我们在上一篇博客中讲到了怎样搭建一个Hibernate框架&#xff0c; 提到Hibernate我们就不得不说他的三大对象&#xff0c;Configuration&#xff0c;SessionFactory &#xff0c; Se…

与Java EE和Spring的集成架构

本周在纽约举行的OReilly软件体系结构大会将举行 。 我很高兴与Josh Long一起提供了有关如何集成Java EE和Spring的教程。 一段时间以来&#xff0c;我们一直在开玩笑。 某些人想到的对两种技术的超级愚蠢见解使我们俩都感到困扰了一段时间。 这次演讲的另一个重要原因是&#…

推广的euclid_欧几里德(Euclid)贴近度评价法在人类进化上的应用

文●螭母&#xff1a;1008一s688 12001)Ol一0006—03 欧几里德(Euclid)贴近度评价法在人类进化上的应用 刘国民1&#xff0c;宋香梅2 (1奉溪拜专&#xff0c;皋溪117022&#xff1b;2&#xff0e;本溪市圆税局&#xff0c;苯澳117022) 搞要&#xff1a;用F唧数学中的欧几里德贴…

HTML个人笔记

<hr/> 水平线标签 <hr style "whidth:80px"/>设置水平线宽度&#xff1b; <hr style "whidth:80%"/>居中 <hr style "whidth:80%" align "left"/>段落的80%&#xff0c;居左&#xff1b; ol>li*5tab生产5…

qt 保存绘制图片时背景变黑_QGraphicsScene绘制背景图片引起的问题

项目是基于Qt的图形视图框架编写的&#xff0c;现有个需求是要在图形中加入自定义的背景图片。心想不就是个背景图片吗&#xff1f;只要重写drawBackground函数我想怎么画就怎么画啊。于是立马从QGraphicsScene类中派生了一个CScene类&#xff0c;并重写了虚函数drawBackground…

JavaScript | JSON基本格式

————————————————————————————————————————————————————————— JSON 语法 "use strict"; // 简单值 "hello,world" // 必须使用双引号// 对象 {"name": "hugh","age&…

Linux命令大全(文件管理)

Linux命令&#xff08;文件管理命令&#xff09; 1、cat命令。用于连接文件并打印到标准输出设备上。 参数: -n 从1开始对所有的输出行数进行编号 -b 和n类似&#xff0c;只是不算空行 -s 大于等于2个空格&#xff08;连续的&#xff09;当一个空格处理 -T 将Tab字符显示…

jmeter 生成计数器_使用密码摘要生成器扩展JMeter

jmeter 生成计数器最近&#xff0c;我不得不处理一个具有50,000条用户记录的OpenLDAP实例&#xff0c;并进行一些压力测试。 JMeter是填充LDAP的最佳选择。 但是&#xff0c;在我的情况下&#xff0c;OpenLDAP配置为不接受任何明文密码。 因此&#xff0c;我无法使用通过JMet…

c++ 查找 list中最长的字符串_查找不重复字符的最长子字符串(编程面试中常见题-用8种编程语言来回答)...

查找不重复字符的最长子字符串&#xff08;编程面试中常见题-用8种编程语言来回答&#xff09;给定一个字符串str&#xff0c;找到不重复字符的最长子字符串。比如我们有 “ABDEFGABEF”, 最长的字符串是 “BDEFGA” 和 “DEFGAB”, 长度为6.再如 “BBBB” 最长字符串是 “B”,…

Spring Async和Java的8 CompletableFuture

众所周知&#xff0c;我不是Spring的最大粉丝&#xff0c;但是当时我在一个组织中工作&#xff0c;该组织使用Spring&#xff08;以不同的形式和版本&#xff09;维护了太多的项目。 我仍然对Spring持怀疑态度&#xff0c;当然有一些很好的主意&#xff0c;有一些很好的&#x…

JustOj 1032: 习题6.7 完数

题目描述 一个数如果恰好等于它的因子之和&#xff0c;这个数就称为"完数"。 例如&#xff0c;6的因子为1、2、3&#xff0c;而6123&#xff0c;因此6是"完数"。 编程序找出N之内的所有完数&#xff0c;并按下面格式输出其因子&#xff1a; 输入 N 输出 ?…

mysql 触发器 本表_MySQL触发器处理本表数据

关于MySQL的触发器&#xff0c;基本上每个Mysql教程里都有讲到&#xff0c;但是我发现那些教程里讲的都是如何处理其他表的数据。在MySQL中写触发器操作关于MySQL的触发器&#xff0c;基本上每个Mysql教程里都有讲到&#xff0c;但是我发现那些教程里讲的都是如何处理其他表的数…

JS 操作cookie

平时网站的开发中cookie用的还是用的比较多的&#xff0c;因为cookie在客户端&#xff0c;所以用js操作的比较多&#xff0c;下面是常用的设置、查找、删除等功能实现。 function addCookie(objName, objValue, objHours){//添加cookie var str objName "" esc…

官方野生蝇群流口水分数

官方是什么&#xff1f; 标题太小&#xff0c;但有用的贡献。 Wildfly Swarm允许我们创建相当小的自包含应用程序&#xff0c;包括我们从Wildfly Application Server中需要的应用程序。 在这篇文章中&#xff0c;我们将研究与Wildfly Swarm合作使用的Drools分数 。 该部分背后的…

SQL-十步完全理解 SQL

十步完全理解 SQL http://blog.jobbole.com/55086/ 刚开始看到了 执行顺序&#xff0c;写得挺好的&#xff0c;明天继续转载于:https://www.cnblogs.com/hpyg/p/7270168.html