异步框架asyn4j的原理
启动时调用init方法
- public void init(){
- if (!run){
- run = true;
- //工作队列
- workQueue = newPriorityBlockingQueue(maxCacheWork);
- //是否存在工作队列满处理类
- if (this.workQueueFullHandler != null) {
- //自定义线程池
- workExecutor = newAsynThreadPoolExecutor(work_thread_num, work_thread_num, 0L,TimeUnit.MILLISECONDS,
- workQueue, new AsynThreadFactory(),new AsynWorkRejectedExecutionHandler(this.workQueueFullHandler),
- executeWorkNum);
- } else {
- workExecutor = newAsynThreadPoolExecutor(work_thread_num, work_thread_num, 0L,TimeUnit.MILLISECONDS,
- workQueue, new AsynThreadFactory(),executeWorkNum);
- }
- //回调函数工作队列
- callBackQueue = newLinkedBlockingQueue();
- //自定义回调函数线程池
- callBackExecutor = newCallBackThreadPoolExecutor(callback_thread_num, callback_thread_num, 0L,
- TimeUnit.MILLISECONDS, callBackQueue,new CallBackThreadFactory(),
- new CallBackRejectedExecutionHandler(),callBackNum);
- //service启动和关闭处理器
- if (this.serviceHandler != null) {
- this.serviceHandler.setServiceStat(0);
- this.serviceHandler.setAsynService(this);
- this.serviceHandler.process();
- }
- //启动工作队列满处理器
- if (this.workQueueFullHandler != null) {
- this.workQueueFullHandler.process();
- }
- //程序关闭后的处理
- Runtime.getRuntime().addShutdownHook(newThread(){
- public void run()
- {
- AsynServiceImpl.this.close(AsynServiceImpl.closeServiceWaitTime);
- }
- });
- }
- }
AsynServiceImpl主要有两个线程池和三个处理器组成
工作线程池AsynThreadPoolExecutor
- public classAsynThreadPoolExecutor
- extends ThreadPoolExecutor
- {
- private AtomicLong executeWorkNum;
回调函数线程池CallbackThreadPoolExecutor
- public classCallBackThreadPoolExecutor
- extends ThreadPoolExecutor
- {
- private AtomicLong callBackNum;
AsynThreadPoolExecutor的executeWorkNum,统计任务的执行数
AsynThreadPoolExecutor的callBackNum,统计回调函数的执行数
ServiceHandler处理器(启动或关闭)
WorkQueueFullHandler处理器(任务数超过maxCacheWork)
ErrorAsynWorkHandler处理器(任务执行异常)
执行时调用addWork方法
- public void addWork(Object tagerObject, Stringmethod, Object[] params, AsynCallBack asynCallBack, WorkWeight weight, booleancache)
- {
- if ((tagerObject == null) || (method ==null)) {
- throw newIllegalArgumentException("target name is null or target method name is null");
- }
- Object target = null;
- //如果对象是String
- if(tagerObject.getClass().isAssignableFrom(String.class)){
- addWorkWithSpring(tagerObject.toString(),method, params, asynCallBack, weight);
- return;
- }
- //如果对象是class
- if ((tagerObject instanceof Class)) {
- String classKey =((Class)tagerObject).getSimpleName();
- //是否缓存,一个class缓存一个默认的对象,防止重复创建
- if (cache)
- {
- target = targetCacheMap.get(classKey);
- if (target == null)
- {
- target =newObject((Class)tagerObject);
- targetCacheMap.put(classKey, target);
- }
- }
- else
- {
- target = newObject((Class)tagerObject);
- }
- }
- else
- {
- target = tagerObject;
- }
- if (target == null) {
- throw newIllegalArgumentException("target object is null");
- }
- //封装成异步任务
- AsynWork anycWork = newAsynWorkEntity(target, method, params, asynCallBack, weight);
- addAsynWork(anycWork);
- }
- public voidaddAsynWork(AsynWork asynWork){
- if (!run) {
- throw new Asyn4jException("asynservice is stop or no start!");
- }
- if (asynWork == null) {
- throw newIllegalArgumentException("asynWork is null");
- }
- try<span style="font-family: Arial, Helvetica, sans-serif;">{</span>
- //通过semaphore来获取许可权限
- if(this.semaphore.tryAcquire(addWorkWaitTime, TimeUnit.MILLISECONDS))
- {
- WorkProcessor workProcessor = newWorkProcessor(asynWork, this);
- workExecutor.execute(workProcessor);
- totalWork.incrementAndGet();
- }
- else{
- log.warn("work queue is full,addwork to cache queue");
- this.workQueueFullHandler.addAsynWork(asynWork);
- }
- }
- catch (InterruptedException e)
- {
- log.error(e);
- }
- }
通过semaphore来控制最大的访问线程数,maxCacheWork就是semaphore的数量,也是工作队列的数量
这里的目的是控制工作队列的数量不能超过maxCacheWork(也可以通过用上限的queue来代替)
如果超过队列maxCacheWork,就用workQueueFullHandler去处理,处理方式同线程池的拒绝策略处理器(
newAsynWorkRejectedExecutionHandler(this.workQueueFullHandler))不过线程池的拒绝策略没用到(前提是队列的有上限的队列),
工作任务WorkProcessor(内含AsynWorkEntity)
- public void run() {
- Thread currentThread =Thread.currentThread();
- if (this.asynWork.getThreadName() != null){
- setName(currentThread,this.asynWork.getThreadName());
- }
- AsynCallBack result = null;
- try{
- result = this.asynWork.call();
- if (result != null) {
- ApplicationContext.getCallBackExecutor().execute(result);
- }
- }
- catch (Throwable throwable){
- if(this.applicationContext.getErrorAsynWorkHandler() != null) {
- this.applicationContext.getErrorAsynWorkHandler().addErrorWork(this.asynWork,throwable);
- }
- }
- finally{
- this.applicationContext.getSemaphore().release();
- }
- }
首先修改线程名称,然后调用asynWork的call方法,如果有回调函数,就执行,如果有异常就执行ErrorAsynWorkHandler,最后Semaphore释放一个许可
AsynWorkEntity
- public AsynCallBack call()
- throws Exception {
- if (this.target == null) {
- throw new RuntimeException("targetobject is null");
- }
- Class clazz = this.target.getClass();
- String methodKey =MethodUtil.getClassMethodKey(clazz, this.params, this.method);
- Method targetMethod =(Method)methodCacheMap.get(methodKey);
- if (targetMethod == null){
- targetMethod =MethodUtil.getTargetMethod(clazz, this.params, this.method);
- if (targetMethod != null) {
- methodCacheMap.put(methodKey,targetMethod);
- }
- }
- if (targetMethod == null) {
- throw newIllegalArgumentException("target method is null");
- }
- Object result =targetMethod.invoke(this.target, this.params);
- if (this.anycResult != null) {
- this.anycResult.setInokeResult(result);
- }
- return this.anycResult;
- }
通过反射技术调用用具体方法,也用缓存技术,anycResult就是你定义的回调函数,没有就返回null
关闭时调用close方法
- publicvoid close(long waitTime){
- if (run){
- run = false;
- try {
- workExecutor.awaitTermination(waitTime,TimeUnit.MILLISECONDS);
- callBackExecutor.awaitTermination(0L,TimeUnit.MILLISECONDS);
- }
- catch (InterruptedException e)
- {
- log.error(e);
- }
- //关闭工作线程和回调函数线程
- workExecutor.shutdown();
- callBackExecutor.shutdown();
- //service关闭处理器
- if (this.serviceHandler != null)
- {
- this.serviceHandler.setAsynWorkQueue(workQueue);
- this.serviceHandler.setCallBackQueue(callBackQueue);
- this.serviceHandler.setServiceStat(1);
- this.serviceHandler.process();
- }
- }
- }
异步框架asyn4j的原理的更多相关文章
- jQuery异步框架探究1:jQuery._Deferred方法
jQuery异步框架应用于jQuery数据缓存模块.jQuery ajax模块.jQuery事件绑定模块等多个模块,是jQuery的基础功能之中的一个.实际上jQuery实现的异步回调机制能够看做ja ...
- 《HiWind企业快速开发框架实战》(1)框架的工作原理
<HiWind企业快速开发框架实战>(1)框架的工作原理 1.HiWind架构 HiWind的基本架构如下: 持久层部分:同时为框架本身的业务服务,也为开发人员的自定义业务服务. 逻辑层: ...
- 无废话Android之内容观察者ContentObserver、获取和保存系统的联系人信息、网络图片查看器、网络html查看器、使用异步框架Android-Async-Http(4)
1.内容观察者ContentObserver 如果ContentProvider的访问者需要知道ContentProvider中的数据发生了变化,可以在ContentProvider 发生数据变化时调 ...
- Spring框架和MVC原理
Spring框架和MVC原理 目录 Spring框架 SpringMVC工作原理 参考资料 回到顶部 Spring框架 Spring当前框架有20个jar包,大致可以分为6大模块: Core Cont ...
- Android 异步框架 RxJava2
观察者模式的概念 RxJava是android的异步框架,官方介绍是可观测的序列,组成异步基于事件程序的库.特点是观察者模式,基于事件流的链式调用,随着异步操作调度过程复杂的情况下,程序逻辑也变得越来 ...
- php框架的制作原理
php框架的制作原理 (2012-08-16 14:25:55) 转载▼ 标签: php框架制作 杂谈 分类: php index.php 主入口文件 <?php define('ISEXIS ...
- 基于SEDA的异步框架设计与实现
基于SEDA的异步框架设计与实现 二.为什么使用SEDA 目前,面对并发环境,主流互联网服务器编程模型有两种:多线程模型以及事件驱动模型.但是这两个模型都不足以解决这个问题.我们来首先看一下这两种编程 ...
- SpringBoot系列之日志框架介绍及其原理简介
SpringBoot系列之日志框架介绍及其原理简介 1.常用日志框架简介 市面上常用日志框架:JUL.JCL.jboss-logging.logback.log4j.log4j2.slf4j.etc. ...
- php面试专题---21、MVC框架基本工作原理考察点
php面试专题---21.MVC框架基本工作原理考察点 一.总结 一句话总结: 会的东西快速过,不要浪费时间,生命有限,都是一些很简单的东西. 1.mvc框架单一入口的 优势 是什么? 可以进行统一的 ...
随机推荐
- ACM/ICPC 之 数据结构-线段树+区间离散化(POJ2528)
这道题用线段树做更方便更新和查询,但是其数据范围很大,因此要将离散化和线段树结合起来,算是一道比较经典的线段树+离散化的例题. 线段树的离散化有很多方法,在这里,我先用一次结点离散化,间接将源左右端点 ...
- UTF8编码转换(C#)
例如: UTF8---ISO-8859-1 string string = "这是中文";Encoding utf8 = Encoding.UTF8; Encoding ISO = ...
- php图片防盗链的小测试
test.php <?php $txt = "http://hiphotos.baidu.com/stupidet/pic/item/4f1b8cfb4c33b7254e4aea69. ...
- 你知道吗?Web的26项基本概念和技术
这是我在网上看到一篇不错的文章,拿出来与大家分享一下:希望有所帮助 作者: 小鱼 来源: 前端里 发布时间: 2014-08-01 22:56 阅读: 10477 次 推荐: 51 原文链 ...
- python基础——第三方模块
python基础——第三方模块 在Python中,安装第三方模块,是通过包管理工具pip完成的. 如果你正在使用Mac或Linux,安装pip本身这个步骤就可以跳过了. 如果你正在使用Window ...
- python基础——sorted()函数
python基础——sorted()函数 排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个d ...
- iOS小技巧总结,绝对有你想要的
原文链接 在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIV ...
- Mysql 调用存储过程的两种方式
一,使用call语句: 如:创建 call 调用: 使用占位符,通过prepare,execute调用:
- C#学习笔记----栈与堆的知识
http://my.oschina.net/lichaoqiang/blog/291906 当我们对.NET Framework的一些基本面了解之后,实际上,还是很有必要了解一些更底层的知识.比如.N ...
- Android之Picasso --zz
简介: Picasso是Square公司开源的一个Android图形缓存库.可以实现图片下载和缓存功能. 特点: 1.加载载网络或本地图片并自动缓存处理: 2.链式调用: 3.图形转换操作,如变换大小 ...