启动时调用init方法

  1. public void init(){
  2. if (!run){
  3. run = true;
  4. //工作队列
  5. workQueue = newPriorityBlockingQueue(maxCacheWork);
  6. //是否存在工作队列满处理类
  7. if (this.workQueueFullHandler != null) {
  8. //自定义线程池
  9. workExecutor = newAsynThreadPoolExecutor(work_thread_num, work_thread_num, 0L,TimeUnit.MILLISECONDS,
  10. workQueue, new AsynThreadFactory(),new AsynWorkRejectedExecutionHandler(this.workQueueFullHandler),
  11. executeWorkNum);
  12. } else {
  13. workExecutor = newAsynThreadPoolExecutor(work_thread_num, work_thread_num, 0L,TimeUnit.MILLISECONDS,
  14. workQueue, new AsynThreadFactory(),executeWorkNum);
  15. }
  16. //回调函数工作队列
  17. callBackQueue = newLinkedBlockingQueue();
  18. //自定义回调函数线程池
  19. callBackExecutor = newCallBackThreadPoolExecutor(callback_thread_num, callback_thread_num, 0L,
  20. TimeUnit.MILLISECONDS, callBackQueue,new CallBackThreadFactory(),
  21. new CallBackRejectedExecutionHandler(),callBackNum);
  22. //service启动和关闭处理器
  23. if (this.serviceHandler != null) {
  24. this.serviceHandler.setServiceStat(0);
  25. this.serviceHandler.setAsynService(this);
  26. this.serviceHandler.process();
  27. }
  28. //启动工作队列满处理器
  29. if (this.workQueueFullHandler != null) {
  30. this.workQueueFullHandler.process();
  31. }
  32. //程序关闭后的处理
  33. Runtime.getRuntime().addShutdownHook(newThread(){
  34. public void run()
  35. {
  36. AsynServiceImpl.this.close(AsynServiceImpl.closeServiceWaitTime);
  37. }
  38. });
  39. }
  40. }

AsynServiceImpl主要有两个线程池和三个处理器组成

工作线程池AsynThreadPoolExecutor

  1. public classAsynThreadPoolExecutor
  2. extends ThreadPoolExecutor
  3. {
  4. private AtomicLong executeWorkNum;

回调函数线程池CallbackThreadPoolExecutor

  1. public classCallBackThreadPoolExecutor
  2. extends ThreadPoolExecutor
  3. {
  4. private AtomicLong callBackNum;

AsynThreadPoolExecutor的executeWorkNum,统计任务的执行数

AsynThreadPoolExecutor的callBackNum,统计回调函数的执行数

ServiceHandler处理器(启动或关闭)

WorkQueueFullHandler处理器(任务数超过maxCacheWork)

ErrorAsynWorkHandler处理器(任务执行异常)

执行时调用addWork方法

  1. public void addWork(Object tagerObject, Stringmethod, Object[] params, AsynCallBack asynCallBack, WorkWeight weight, booleancache)
  2. {
  3. if ((tagerObject == null) || (method ==null)) {
  4. throw newIllegalArgumentException("target name is null or  target method name is null");
  5. }
  6. Object target = null;
  7. //如果对象是String
  8. if(tagerObject.getClass().isAssignableFrom(String.class)){
  9. addWorkWithSpring(tagerObject.toString(),method, params, asynCallBack, weight);
  10. return;
  11. }
  12. //如果对象是class
  13. if ((tagerObject instanceof Class)) {
  14. String classKey =((Class)tagerObject).getSimpleName();
  15. //是否缓存,一个class缓存一个默认的对象,防止重复创建
  16. if (cache)
  17. {
  18. target = targetCacheMap.get(classKey);
  19. if (target == null)
  20. {
  21. target =newObject((Class)tagerObject);
  22. targetCacheMap.put(classKey, target);
  23. }
  24. }
  25. else
  26. {
  27. target = newObject((Class)tagerObject);
  28. }
  29. }
  30. else
  31. {
  32. target = tagerObject;
  33. }
  34. if (target == null) {
  35. throw newIllegalArgumentException("target object is null");
  36. }
  37. //封装成异步任务
  38. AsynWork anycWork = newAsynWorkEntity(target, method, params, asynCallBack, weight);
  39. addAsynWork(anycWork);
  40. }
  1. public voidaddAsynWork(AsynWork asynWork){
  2. if (!run) {
  3. throw new Asyn4jException("asynservice is stop or no start!");
  4. }
  5. if (asynWork == null) {
  6. throw newIllegalArgumentException("asynWork is null");
  7. }
  8. try<span style="font-family: Arial, Helvetica, sans-serif;">{</span>
  1. //通过semaphore来获取许可权限
  2. if(this.semaphore.tryAcquire(addWorkWaitTime, TimeUnit.MILLISECONDS))
  3. {
  4. WorkProcessor workProcessor = newWorkProcessor(asynWork, this);
  5. workExecutor.execute(workProcessor);
  6. totalWork.incrementAndGet();
  7. }
  8. else{
  9. log.warn("work queue is full,addwork to cache queue");
  10. this.workQueueFullHandler.addAsynWork(asynWork);
  11. }
  12. }
  13. catch (InterruptedException e)
  14. {
  15. log.error(e);
  16. }
  17. }

通过semaphore来控制最大的访问线程数,maxCacheWork就是semaphore的数量,也是工作队列的数量

这里的目的是控制工作队列的数量不能超过maxCacheWork(也可以通过用上限的queue来代替)

如果超过队列maxCacheWork,就用workQueueFullHandler去处理,处理方式同线程池的拒绝策略处理器(

newAsynWorkRejectedExecutionHandler(this.workQueueFullHandler))不过线程池的拒绝策略没用到(前提是队列的有上限的队列),

工作任务WorkProcessor(内含AsynWorkEntity)

  1. public void run() {
  2. Thread currentThread =Thread.currentThread();
  3. if (this.asynWork.getThreadName() != null){
  4. setName(currentThread,this.asynWork.getThreadName());
  5. }
  6. AsynCallBack result = null;
  7. try{
  8. result = this.asynWork.call();
  9. if (result != null) {
  10. ApplicationContext.getCallBackExecutor().execute(result);
  11. }
  12. }
  13. catch (Throwable throwable){
  14. if(this.applicationContext.getErrorAsynWorkHandler() != null) {
  15. this.applicationContext.getErrorAsynWorkHandler().addErrorWork(this.asynWork,throwable);
  16. }
  17. }
  18. finally{
  19. this.applicationContext.getSemaphore().release();
  20. }
  21. }

首先修改线程名称,然后调用asynWork的call方法,如果有回调函数,就执行,如果有异常就执行ErrorAsynWorkHandler,最后Semaphore释放一个许可

AsynWorkEntity

  1. public AsynCallBack call()
  2. throws Exception {
  3. if (this.target == null) {
  4. throw new RuntimeException("targetobject is null");
  5. }
  6. Class clazz = this.target.getClass();
  7. String methodKey =MethodUtil.getClassMethodKey(clazz, this.params, this.method);
  8. Method targetMethod =(Method)methodCacheMap.get(methodKey);
  9. if (targetMethod == null){
  10. targetMethod =MethodUtil.getTargetMethod(clazz, this.params, this.method);
  11. if (targetMethod != null) {
  12. methodCacheMap.put(methodKey,targetMethod);
  13. }
  14. }
  15. if (targetMethod == null) {
  16. throw newIllegalArgumentException("target method is null");
  17. }
  18. Object result =targetMethod.invoke(this.target, this.params);
  19. if (this.anycResult != null) {
  20. this.anycResult.setInokeResult(result);
  21. }
  22. return this.anycResult;
  23. }

通过反射技术调用用具体方法,也用缓存技术,anycResult就是你定义的回调函数,没有就返回null

关闭时调用close方法

    1. publicvoid close(long waitTime){
    2. if (run){
    3. run = false;
    4. try {
    5. workExecutor.awaitTermination(waitTime,TimeUnit.MILLISECONDS);
    6. callBackExecutor.awaitTermination(0L,TimeUnit.MILLISECONDS);
    7. }
    8. catch (InterruptedException e)
    9. {
    10. log.error(e);
    11. }
    12. //关闭工作线程和回调函数线程
    13. workExecutor.shutdown();
    14. callBackExecutor.shutdown();
    15. //service关闭处理器
    16. if (this.serviceHandler != null)
    17. {
    18. this.serviceHandler.setAsynWorkQueue(workQueue);
    19. this.serviceHandler.setCallBackQueue(callBackQueue);
    20. this.serviceHandler.setServiceStat(1);
    21. this.serviceHandler.process();
    22. }
    23. }
    24. }

异步框架asyn4j的原理的更多相关文章

  1. jQuery异步框架探究1:jQuery._Deferred方法

    jQuery异步框架应用于jQuery数据缓存模块.jQuery ajax模块.jQuery事件绑定模块等多个模块,是jQuery的基础功能之中的一个.实际上jQuery实现的异步回调机制能够看做ja ...

  2. 《HiWind企业快速开发框架实战》(1)框架的工作原理

    <HiWind企业快速开发框架实战>(1)框架的工作原理 1.HiWind架构 HiWind的基本架构如下: 持久层部分:同时为框架本身的业务服务,也为开发人员的自定义业务服务. 逻辑层: ...

  3. 无废话Android之内容观察者ContentObserver、获取和保存系统的联系人信息、网络图片查看器、网络html查看器、使用异步框架Android-Async-Http(4)

    1.内容观察者ContentObserver 如果ContentProvider的访问者需要知道ContentProvider中的数据发生了变化,可以在ContentProvider 发生数据变化时调 ...

  4. Spring框架和MVC原理

    Spring框架和MVC原理 目录 Spring框架 SpringMVC工作原理 参考资料 回到顶部 Spring框架 Spring当前框架有20个jar包,大致可以分为6大模块: Core Cont ...

  5. Android 异步框架 RxJava2

    观察者模式的概念 RxJava是android的异步框架,官方介绍是可观测的序列,组成异步基于事件程序的库.特点是观察者模式,基于事件流的链式调用,随着异步操作调度过程复杂的情况下,程序逻辑也变得越来 ...

  6. php框架的制作原理

    php框架的制作原理 (2012-08-16 14:25:55) 转载▼ 标签: php框架制作 杂谈 分类: php index.php 主入口文件 <?php  define('ISEXIS ...

  7. 基于SEDA的异步框架设计与实现

    基于SEDA的异步框架设计与实现 二.为什么使用SEDA 目前,面对并发环境,主流互联网服务器编程模型有两种:多线程模型以及事件驱动模型.但是这两个模型都不足以解决这个问题.我们来首先看一下这两种编程 ...

  8. SpringBoot系列之日志框架介绍及其原理简介

    SpringBoot系列之日志框架介绍及其原理简介 1.常用日志框架简介 市面上常用日志框架:JUL.JCL.jboss-logging.logback.log4j.log4j2.slf4j.etc. ...

  9. php面试专题---21、MVC框架基本工作原理考察点

    php面试专题---21.MVC框架基本工作原理考察点 一.总结 一句话总结: 会的东西快速过,不要浪费时间,生命有限,都是一些很简单的东西. 1.mvc框架单一入口的 优势 是什么? 可以进行统一的 ...

随机推荐

  1. ACM/ICPC 之 数据结构-邻接表+BFS(TSH OJ-无线广播Broadcast)

    这道题中若能够构成互不干扰的区域,其构成的图其实就是汉密尔顿路(Hamilton road),因此如果能够观察出来可以直接转化为汉密尔顿路的存在性证明,即便不能观察,我相信ACMer也能转化为BFS问 ...

  2. [转]Android中Application类的用法

    原文链接:http://www.cnblogs.com/renqingping/archive/2012/10/24/Application.html Application类 Application ...

  3. WebService及WCF获取客户端IP,端口

    wcf获取客户端IP,端口 var context = OperationContext.Current; var properties = context.IncomingMessageProper ...

  4. nohup后台运行jar

    nohup 用途:LINUX命令用法,不挂断地运行命令.  语法:nohup Command [ Arg ... ] [ & ]  描述:nohup 命令运行由 Command 参数和任何相关 ...

  5. struts2封装客户端数据到Action

    1.在Action中定义简单数据类型的属性 给Action定义简单类型的属性,封装客户端请求的数据 简单类型:String,基本类型和对应的引用类型 只要保证客户端请求的参数名称和Action的属性名 ...

  6. Spetember 5th 2016 Week 37th Monday

    No matter how far you may fly, never forget where you come from. 无论你能飞多远,都别忘了你来自何方. Stay true to you ...

  7. 用Mysqlbinlog备份BinLog文件

    默认情况下, mysqlbinlog读取二进制文件[BinLog]并以文本的方式呈现[text format].mysqlbinlog可以直接地从本地读取Log,也可以读取远程的Log[--read- ...

  8. hdu1722(gcd)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1722 题意:要使一块蛋糕既能均分给a个人,又能均分给b个人,问至少需要分成几块(不需要每块都一样大小) ...

  9. NYOJ题目770仿射密码

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAs4AAAIUCAIAAACFKz0yAAAgAElEQVR4nO3dPXLruLaG4TsJ5RqIYw

  10. java的system.arraycopy()方法

    java.lang.System的静态方法arraycopy()可以实现数组的复制,讲课的老师说这个方法效率比较高,如果数组有成千上万个元素,那么用这个方法,比用for语句循环快不少.于是我试了试,发 ...