异步框架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框架单一入口的 优势 是什么? 可以进行统一的 ...
随机推荐
- PHP javascript cookie
2015-07-30 16:54:58 ................................cao!!!! 汉字, 邮箱的@符号 容易出错 PHP setcookie 的时候, 不要url ...
- Java for LeetCode 224 Basic Calculator
Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...
- C++库(Thrift)
Thrift通信框架 0 简介 Thrift是一个软件通讯框架,用来进行可扩展且跨语言的服务的开发,最初由Facebook于2007年开发,2008年进入Apache开源项目.它结合了功能强大的软件堆 ...
- 【mongo】drop不释放磁盘空间
用drop删除mongo的collection后,其size归零,但是storage仍然是原大小,磁盘空间没有被释放. 要用下面命令释放无用的磁盘空间 mongod -repair
- 用css解决iframe的自适应问题(跨域下同样有用)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
- 配置TFS2010的用户截图
先要添加一个管理用户
- Sql如何自动定时备份数据库
直接上图
- eclipse maven tomcat7 热部署
.配置tomcat a.配置jdk b.CATALINA_HOME=c:\tomcat CATALINA_BASE=c:\tomcat .tomcat配置密码 C:\Program Files\oth ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(三) 之 实现单聊,群聊,发送图片,文件。
上篇讲解了如何搭建聊天服务器,以及客户端js怎么和layui的语法配合.服务器已经连接上了,那么聊天还会远吗? 进入正题,正如上一篇提到的我们用 Client.Group(groupId)的方法向客户 ...
- Java多线程---同步与锁
一,线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 二.同步和锁定 1.锁的原理 Java中每个对象都有一个内置锁. 当程序运行到非静态的synchronized同步方法上时,自动 ...