启动时调用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 之 暴力打表(求解欧拉回路)-编码(POJ1780)

    ///找到一个数字序列包含所有n位数(连续)一次且仅一次 ///暴力打表 ///Time:141Ms Memory:2260K #include<iostream> #include< ...

  2. jquery.base64.js简单使用

    jquery.base64.js, 加密,使用,先引入jquery,然后引入jquery.base64.js 使用如下 js中加密如下 $.base64.encode(result[i].ipadre ...

  3. 【python】An Introduction to Interactive Programming in Python(week two)

    This is a note for https://class.coursera.org/interactivepython-005 In week two, I have learned: 1.e ...

  4. ios NSLayoutConstraint

    为了让我们的应用在不同尺寸的屏幕下都能 “正常”的表示,我们尽量不要把数据写死.大多数可视元素都是一个矩形区域,当然这个矩形区域有坐标的,我们有了这个区域坐标就能确定可视元素的现实位置了.但是ipho ...

  5. IOS- Run Loops

    Run Loops Run loops是线程相关的的基础框架的一部分.一个run loop就是一个事件处理的循环,用来不停的调度工作以及处理输入事件.使用run loop的目的是让你的线程在有工作的时 ...

  6. Jquery选中行实现行中的Checkbox的选中与取消选中

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs& ...

  7. iOS进阶面试题----Block部分

    1 什么是block 对于闭包 (block),有很多定义,其中闭包就是能够读取其它函数内部变量的函数,这个定义即接近本质又较好理解.对于刚接触Block的同学,会觉得有些绕, 因为我们习惯写这样的程 ...

  8. ios block中引用self

    __block __weak typeof(self) tmpSelf = self; ^(){ tmpSelf...... }

  9. String[] a = new String[]{"1","2"},我如果想增加一个"3"到a中,如何增加?

    在java中数组是定长的,当你声明了数组的大小后数组的长度就不能改变在你的程序中,数组的初始化大小为2,a[0]="1";a[1]="2",所以无法产生元素a[ ...

  10. JavaScript的内置对象和浏览器对象

    在javascript中对象通常包括两种类型:内置对象和浏览器对象,此外,用户还可以自定义对象. 对象包含两个要素:1.用来描述对象特性的一组数据,也就是若干变量,通常称为属性.2.用来操作对象特性的 ...