self up1.JMS是异步的,但异步的不都是JMS。
2.参数传递无法使用Object[] 因为那样会导致把业务代码移入Excuter之内。

解决方案 »

  1.   

    只有UP??是我没说清楚,还是我说的东西太高深了?是大家太谦虚了,呵呵
    UP!
      

  2.   

    你的代码不是一个完整的实现,按照你的思路,应该是先调用业务方法,再调用取值的方法,如果没有值,就等待或轮循对吗?
    我认为如果这样,异步调用系统就不如采用基于事件驱动的方式,可使调用端和被调用端充分解耦。
    不过jms就是这样实现的。
      

  3.   

    to cowstar(牛郎星)我的确非常拽。因为我是高手。 to chesterwoo() 不是很明白你的意思。
    我的异步框架把一个同步方法doSomething拆成了两部分,doSomethingRequest和doSomethingResponse,以此达到异步的目的。另外,asyn框架的确是事件驱动的。还有,这个框架和JMS毫无关系,它的目的是解决一些常规的编程问题。
      

  4.   

    刚才我没有完全理解你的设计意图,我理解这个调用实现了register/notify的方式(同.net的代理方式不同,java的创始人认为.net的方式是错误的,不知是不是门户之见),同java的图形控件使用的响应方式相同,但是Executer会启动一个线程去执行封装在Command实例中的代码。
    我的原意是将数据而不是数据+业务方法,封装在事件中,将事件发送至被调用端,被调用端会执行相应的业务方法。
    看来在你的设计中,被调用端主要是一个异步执行代码的线程池,而不是一个业务组件。这样需要统一接口,所以使用了Command,但是被调用端不会理解传入参数真正的意义,因为是Object[],而执行不同的业务代码需要载入不同的类,这样问题就出来了。如果这次我的理解没有问题,我想只有几种方法可以实现。最可能的应该是在被调用端使用线程的类装载器去动态载入封装业务方法和数据的类,这个类会设计成为一个外部类,而不是内部类。这样做需要同时通知被调用端,这是哪一个相关业务,通过配置文件,被调用端找到并载入相应的类,而这个类知道传入参数的真正意义。这样就解决类型的问题,但我觉得这样是否有价值需要看业务的需要,如果是一个非常重的业务,也许有价值,因为等待的代价超出了性能上的牺牲。理解也许不对,大家一起来讨论吧。
      

  5.   

    如果是我,我会这么设计1.定义一个Command类,简单的属性类,属性包括传入参数,执行目标类,执行目标类的方法名,响应目标类(可以使调用者本身this),响应目标类的响应方法等.2.一个Command队列3.一个处理器,可以配置为自动启动或手工启动,处理器扫描Command队列,多线程并发处理Command运用反射机制调用执行目标类的执行目标方法,如执行完毕调用响应类的响应方法.好处:
    耦合比较小,可以产生Command就扔到队列里不管,不必实现什么接口就可以用,对于多个参数也可以灵活的处理.重点:Command类的属性设计有点消息的意思,考虑的很匆忙,很不全面,欢迎大家批评.学习楼主的设计
      

  6.   

    其实我觉得这个异步调用框架的优点是,均衡了执行时间和实现了非阻塞,缺点是牺牲一部分性能。
    不知道你的设计应用领域在哪里?to xue_sharp(向左走,向右走):
    如果这个调用框架还要支持远程调用的话,返回方式就可能是轮询或异步通讯,有点像消息中间件。
      

  7.   

    to:chesterwoo() 这么个小东西没必要搞那么复杂。更简单甚至可以Command队列都去掉,直接执行command。但是多了一个队列还是可以有很多好处的,可以统一对大量的异步请求进行控制,比如控制一个长时间的操作被短时间内被并发重复的调用。当然这个队列实现的控制管理功能也可以放在处理器内部来完成。分布式异步不还是有JMS这个大家伙吗:)
      

  8.   

    hehe,有了更简单的想法,1个类就可以搞定,我就是喜欢简单的东西class foo {
    void begin() {};
    void end() {};
    void test() {
    Command com = new Command(this,"begin",this,"end");
    com.run();
    }
    }
      

  9.   

    to chesterwoo()
    你的理解是对的。asyn使用了register/notify的Observer设计模式。看这里的代码:
     Command c=new Command(this,"doSomething")...this关键字其实就是用来向Executer注册自己,以在异步方法完成后能够收到通知。有点不同的是,Observer模式是“一对多”,一个对象通知多个对象。而asyn框架则是“一对一”。-------“我的原意是将数据而不是数据+业务方法,封装在事件中,将事件发送至被调用端,被调用端会执行相应的业务方法。”这个意见以及你其后提出的解决方案,我在设计的时候思考过,是有问题的。
    Executer是一个单纯的执行器,它的作用是执行异步方法,并在完成后通知前端。它是一个通用组件,因此它不可能涉及到具体的业务代码。所以惟有使用多态原理,使得Executer只管执行,而不管执行的是什么。-------“在被调用端使用线程的类装载器去动态载入封装业务方法和数据的类”其实,Command类就是“封装业务方法和数据的类”。所以与其在Executer端载入类,还不如在请求端就载入,然后再传入Executer对象。这样做的一个很大好处是Command的实现作为请求端的内部类可以共享请求端的域。当然如果没有这样的必要,考虑灵活性,可以把Command的实现类作为外部类,然后通过“依赖注入”动态载入(不过这个动态载入发生在请求端,而不是Executer内。目前我的一个已经运行的程序就是这么做的)。to xue_sharp(向左走,向右走)
    觉得你的设计不是很好。------“定义一个Command类,简单的属性类,属性包括传入参数,执行目标类,执行目标类的方法名,响应目标类(可以使调用者本身this),响应目标类的响应方法等.”这样太繁复了。首先在请求端就要为Command对象注入大量业务无关的参数--类型、方法名等等反射参数。其次在Executer端需要解析这些参数,catch大量的Exception。------“2.一个Command队列”Executer拥有一个Command对列。当向同一个Executer发送两个Command对象时,Executer会依次执行它们。不过这在我的设计中不是主要的。---------------------------
    class foo {
    void begin() {};
    void end() {};
    void test() {
    Command com = new Command(this,"begin",this,"end");
    com.run();
    }
    }
    ---------------------------
    这个的确非常简单,但它不能解决实际问题。
    首先begin和end的传入参数如何处理?begin和end的返回参数如何处理?异常又如何处理?对于业务而言,end和test的函数签名是不定的,那如果对Command传入函数所需参数的话,只能使用Object[]。但Command又如何理解Object[]数组真正的含义呢?也许你会说“使用reflection”,但reflection也有局限,用在此处于事无补。
      

  10.   

    to xue_sharp(向左走,向右走):我的想法就是直接执行Command,但传递给被调用端的不包含方法签名参数,而是代理业务名。被调用端由配置文件找到相应的Command,由被调用端线程的类装载器载入并执行。不然,被调用端不会知道处理哪一个Command。其实这样处理,都是基于这样一个假设,这个异步调用框架支持远程处理才能充分发挥能力。
    如果不需要远程处理,直接传递Command的引用,而不是配置文件对应,效率要好一些。Command的列表可以看作一个请求的缓冲,比直接调用增加了并发请求的处理能力和控制能力。
      

  11.   

    to alienbat(亡灵法师) :可能你没有完全理解我的意图,我明白你设计的是一个通用的调用框架,而不是业务相关的。实际上,框架端并不需要加入任何业务代码,只要将业务封装到Command中,框架端能过动态的发现并载入这个Command就可以了。由于使用配置文件,或直接传引用,框架端不需要知道具体业务,只要找到Command类,并调用Command的统一接口就可以了。(这里Command不就是一个Command模式的实现嘛)。简单的讲,这个框架的核心就是执行拿过来的代码,而不去理解拿过来代码的意义。
      

  12.   

    to alienbat(亡灵法师) :如果不考虑改造为远程调用,直接传递给框架端Command的引用就可以了,不需要类装载器载入。
      

  13.   

    to alienbat(亡灵法师) :同步与异步的切换应该是在调用端,而不是框架端配置。
      

  14.   

    to chesterwoo()我说的就是这个意思。
    另外asyn尚无法实现“同步与异步的切换”。to xue_sharp(向左走,向右走)asyn是能在实现它的既定目标的前提下最为简单的。在设计时,我已经尽可能地减少框架对业务代码的扰动。我不认为asyn“玩弄了名词”或者“生涩地套用了模式”。
      

  15.   

    to alienbat(亡灵法师):我认为同步与异步的切换的处理应该在调用端,调用框架只知道处理后通知。如何接受通知(同步或异步)是调用端的工作。
    在调用端切换是可以实现,可能你也考虑过。to xue_sharp(向左走,向右走), alienbat(亡灵法师) and all:另外,我对这个框架的可行性很感兴趣,就是这个框架解决什麽问题?是不是最好的方案?扩展到远程调用有没有必要?理由?框架在本地和远程的性能如何?该性能同业务量和并发量有什麽关系?
      

  16.   

    能够同步异步切换当然是最好。但目前我无法实现这一目标,asyn框架同样也不可以。“方法”都是同步的,压根没有“异步方法”这一说。我所谓的“异步方法”,其实是一对同步方法:一个(request)用来执行业务代码,一个(response)用来响应结果。同步模式只需要书写一个方法,里面放业务逻辑,用asyn实现异步模式则需要书写两个方法并执行特定的语句(虽然我尽力把这些减到最少,但毕竟有)。这些都是硬编码,是无法动态切换的。本框架和远程调用没什么关系。它可以用于任何执行耗时但又必须避免线程阻塞场所----比如查找1,000,000以内的质数,比如远程方法调用。事实上我做这个框架的初衷就是为了对付远程调用耗时过长引起的线程阻塞。
      

  17.   

    我就比較喜歡xue_sharp(向左走,向右走)的方法,簡單、直接。
    模式應該放在具體的應用才來討論吧。
      

  18.   

    SB
    你这不叫框架
    顶多算个sample