专利名称:Applet线程模型及基于Applet线程模型的调用构件的方法
技术领域:
本发明是关于一种计算机构件化软件之间的调用方法,尤其是指构件之间的基于
一种线程模型的调用方法及该种线程模型。
背景技术:
每个Applet构件可以看作是一个独立的应用,一个自封闭的运行空间,即便是同 一个进程内的Applets,它们之间的数据也是相对独立的,各自有专属的线程执行各自的代 码,有着清晰的Applet边界。 但是当Applet之间发生调用关系时,比如一个通讯录的Applet可能会调用Email 的Applet来完成"点击通讯录中Email地址直接弹出编辑新邮件"的功能,类似的Applet 之间调用可能还有很多,对于一个Applet来说,如果它的功能实现可能被多个Applet并 发调用,或者说它的代码可能会运行在不同的Applet这中,可能会给Applet实现者造成 诸多难以预计的困难和假设。首先要考虑多线程并发调用的互斥关系,对于一个功能简单 的Applet来说,它可能只需要一个Applet主线程即可完成所有功能,但却要为了防止被其 它Applet调用而考虑多线程问题;再比如,进程内所有线程都属于某个Applet,那么任意 Applet的成员方法里调用Api获得当前Applet的句柄都应该是它所属的Applet,但由于 Applet可能被其它Applet调用,所以它获得的Applet句柄不确定是哪个Applet,如果它 的功能实现方法对此有依赖,处理起来就比较复杂。因此Applet在互相调用存在多线程并 发调用的问题。 其实Applet可以看作一个轻量级的进程。而进程之间的调用过程是这样的跨进 程调用时,发起调用的一方的调用线程等待在被调用一方的进程边界,由被调用一方的进 程内线程完成调用,并将结果返回给调用一方等待中的线程,完成一次跨进程调用。
发明内容
鉴于以上内容,有必要提供一种Applet线程模型及基于该线程模型的构件调用 的方法。 所述Applet线程模型包括A卯let构件和具有Applet属性的构件;属于该 Applet构件的消息队列及回调线程。 其中,Applet构件和具有Applet属性的构件都具备夹壁墙和一个Event对象。 所述夹壁墙用来拦截和存放调用方构件的调用请求线程。所述Applet构件用于将调用请 求打包成一个调用消息包,通过投递回调机制将该调用消息包投递到所述消息队列等待处 理;所述回调线程用于当从消息队列接收到该调用消息包时,调用并执行所述目标接口方 法,将执行结果返回给等待在所述构件夹墙壁中的调用请求线程,并激发该构件的Event 对象;所述Event对象用于被回调线程激发后,通知被拦截在所述构件夹壁墙里进行等待 的调用请求线程去获取执行结果以将该执行结果返回给调用方构件。
所述基于该Applet线程模型的构件调用方法包括步骤目标构件利用编译工具 生成打包函数,该打包函数经编译生成DLL可执行文件;创建该目标构件对象,调用方构件 向该创建的目标构件对象发出调用请求;拦截该调用请求并将其存放在目标构件的夹壁 墙,由打包函数将该调用请求打包成一个调用消息包;目标构件对象利用投递回调事件的 机制将上述调用消息包投递到其所属的消息队列中;当消息队列处理到该调用消息包时, 回调线程从该消息队列接收该调用消息包;该回调线程调用并执行所述的目标接口方法, 将执行结果返回给等待在所述夹壁墙里的调用请求,并触发该目标构件对象的Event对 象;该Event对象通知该调用请求去获取返回的执行结果,该调用请求将获取的执行结果 返回给调用方构件。 本发明利用构件所特有的夹壁墙技术,将所有针对Applet和具有Applet属性的 构件对象的接口方法的调用,都在夹壁墙中拦截,再将调用的参数和被调用的接口方法的 信息一起打包,通过投递回调事件的机制向被调用的Applet的消息队列中投递此次调用 事件。此时调用线程进入等待状态,当被调用的Applet的消息循环处理到这次调用事件 时,由Applet的回调线程执行目标接口方法,执行完成后再将结果返回给等待在夹壁墙的 调用线程,再由它返回给调用方的Applet,由此完成一次完整的调用。
利用本发明可以解决App 1 et彼此调用时多线程问题,加强App 1 et之间的独立性, 使得外界对Applet数据结构的访问和接口方法的调用只能通过Applet自己的线程来完 成。
图1是本发明较佳实施例的线程模型示意图。 图2是本发明应用Applet线程模型调用构件目标接口方法的流程图。
具体实施例方式
如图1所示,是本发明较佳实施例的Applet线程模型1的示意图。需要说明的是 该Applet线程模型1适用于所有的Applet构件和所有被Applet属性修饰的普通构件。
从其他Applet构件或者从"外部"调用一个Applet构件的方法,或者调用一个具 有Applet属性的构件的方法,都会应用Applet线程模型。在本较佳实施例中,将被调用的 Applet构件或具有Applet属性的构件称为目标Applet构件,将调用该目标Applet构件的 其他Applet构件或"外部"的构件称为调用方构件。 所述的Applet线程模型1包括Applet构件/具有Applet属性的构件(也即目 标构件10)、属于该Applet构件/具有Applet属性的构件的消息队列11和回调线程12。 其中每个Applet构件都有属于自己的消息队列11和回调线程12。 其中,每个构件都具备夹壁墙101和一个Event对象102。所述夹壁墙101用来存 放所有调用该构件的调用方的请求线程,也即是说所有调用该构件的调用请求线程都会被 拦截在该构件的夹壁墙101里。 例如用下面的一段程序代码(aa)实现目标构件TMail的夹壁墙101的功能
_TMail: :GetMailer (Mail**ppMailer) 〃夹壁墙函数;
{
TMailGetMailerParam param ;〃创建一个调用消息包的对象; ECode ec = CEvent: :New(¶m. —pEvent);〃创建一个操作系统 Event对象,当这次调用被回调线程处理完以后通过设置这个事件通
知调用者; if(FAILED (ec))return ec ; param. _ec = N0ERR0R ; param. _pThis = this ;〃设置调用参数; param. —ppMailer = ppMailer ;〃设置调用参数; ec = PostCallbackEvent(MAKE_PARAMETER(&_TMail_GetMailer, ¶m));〃将这次"调用消息包"投递到消息队列; if (FAILED (ec)) {〃如果投递"调用消息包"失败; param. _pEvent_>Release ();〃释放先前创建的对象; return ec ;〃返回错误码; } param._pEvent->Wait (INFINITE);〃无限期等待这个Event对象被 触发,当回调线程处理完这次调用时会触发这个Event ;
param. _pEvent_>Release ();〃等待结束,不再需要这个Event对
象,释放它; if (param. _ec = = N0ERR0R) {〃如果调用成功则获取out参数; ppMailer = param. —ppMailer ;//获取out参数; } return param. _ec ;〃将调用结果的返回值返回; } 该程序代码段(aa)可以看作是目标构件TMail的的夹壁墙函数。 所述Event对象102是在该夹壁墙函数中被设置的,以用于当所调用的目标构件
的方法被执行完后,通过触发该设置的Event对象通知被拦截在夹壁墙101里进行等待的
调用方的调用请求线程。 所述消息队列11是一个属于该目标构件的Applet消息队列,用来存放所有的调 用该目标构件的调用消息包。所述的在消息队列中等待的调用消息包所包括的信息如下 调用参数及被调用的目档构件的接口方法。目标构件利用打包函数将调用方的调用请求中 的调用参数及被调用的目标构件的接口方法等信息一起打包成一个调用消息包,再通过投 递回调事件机制将该调用消息包投递到该消息队列中排队等待处理。如打包函数所用的打 包调用参数的数据结构可以用下面的一段程序代码(bb)实现
TMail: :GetMailer(Mail**ppMailer)〃GetMailer的声明;
typedef struct_TMail_GetMailer_Param{〃这是TMail构件的GetMailer方法 的调用消息包的数据结构定义,该结构由编译工具根据GetMailer的参数自动生成;
IMail氺氺—ppMailer ;//又寸应函数声日月中白勺ppMailer ;
_TMail*_pThis ;〃被调用的TMail对象的this指针;
ECode_eC ;〃当调用结束后,保 GetMailer的返回值;
IEVent*_pEVent ;〃调用者创建Event对象,被调用的回调线程在调用结束后触 发这个Event对象,使调用者知道该次调用已经结束;
)TMailGetMailerParam; 所述回调线程12即是Applet的主线程,与Applet —一对应,而Applet里可以包 含很多构件对象。该回调线程12用于当消息队列11的消息循环处理流程处理到该调用消 息包时,调用所注册的回调函数,该回调函数是自动生成的代码,由该回调函数再调用所述 目标构件的接口方法并执行该接口方法,将执行结果返回给等待在目标构件10的夹墙壁 101中的调用方构件的调用请求线程,并激发该目标构件的Event对象,让该Event对象通 知等待在夹墙壁101里的调用请求线程去获取返回的执行结果。该调用请求线程将所获取 的结果返回给调用方构件。由此完成一次目标构件的接口方法的调用。
例如,当调用的目标构件是TMailer时,可以用下面的一段程序代码(cc)实现所 述回调函数的功能 ECode_TMail_GetMailer(TMailGetMailerParam*pParam) {〃这个函数由编译工具自动生成,当回调线程从消息队列里收到对GetMailer 的"调用消息包"时,调用此函数; pParam_>_ec = pParam_>_pThis_>TMail::GetMailer(&pParam_> _ppMailer);〃调用TMail的GetMailer方法,并将返回值保存在
消息包参数ec里; pParam->_pEvent->SetEvent ();〃调用结束,触发Event对象; return N0ERR0R ; } 其中消息队列11的消息循环处理流程会按顺序处理在消息队列中等待的调用消 息包,并通知回调线程接收所述调用消息包,直到消息队列为空。这个过程是一个循环过 程。 从其它Applet或者从"外部"调用一个Applet构件的方法,或者调用一个具有 Applet属性的构件的方法,都会应用"Applet线程模型",这次调用会被打包成一个调用消 息包,投递到目标Applet的消息队列,再由目标Applet的回调线程完成调用,并保存调用 结果,最终调用者获得调用结果返回,完成一次调用。 参阅图2所示,是应用Applet线程模型调用目标构件方法的流程图。 步骤S200,目标构件利用编译工具生成打包函数,如上述程序代码段bb。在此所
述目标构件为具有Applet属性的普通构件类对象,所述之目标接口方法为Applet对象所
实现的所有接口方法。 步骤S202,该打包函数经编译生成DLL可执行文件。 步骤S204,在本较佳实施例中,该调用方构件需向目标构件TMail调用其 GetMai 1 er接口方法,则创建该目标构件对象,如TMai 1对象,并向该TMai 1对象发出包含调 用参数及被调用的接口方法信息的调用请求。 步骤S206,该调用请求线程被拦截在目标构件的夹壁墙101中,并由上述打包函 数将该调用请求线程中的调用参数及被调用的接口方法等信息打包成一个调用消息包。
步骤S208,目标构件对象利用投递回调事件的机制将上述调用消息包投递到其所
7属的消息队列中。此时该调用请求线程在目标构件对象的夹壁墙101中进行等待。所述调 用消息包在该消息队列中排队等待处理。 步骤S210,当消息队列的消息循环处理流程处理到该调用消息包时,回调线程12 从该消息队列接收该调用消息包,也即该回调线程接收到了该调用方构件向目标构件对象 发出的调用请求事件。 步骤212,该回调线程12调用回调函数以调用并执行所述的目标接口方法,如 GetMailer。所述的回调函数如上述之程序代码段cc。该回调线程12将执行目标接口方法 的结果返回给等待在目标构件对象的夹壁墙101里的调用请求线程,然后触发该目标构件 对象的Event对象102。 步骤S214,该Event对象通知该调用请求线程去获取返回的执行结果,该调用请 求线程获取返回的执行结果并将该执行结果返回给调用方构件。 下面通过几段代码片断来说明应用本发明的Applet线程模型的优点。在下面 所述的几段代码片断中,目标构件对象是TMail构件和一个具有Applet属性的构件对象 CMail,所需调用的接口方法分别的TMail的GetMailer方法和CMail的SendMail方法。
(l)Mail. car〃 一个邮件发送接收服务的构件定义文件
Interface Mail {〃定义构件的接口 SendMail (WString title, WString to, WString context);(〃声明所定义的构
件的接口方法 } interface Manager {〃定义构件接口 GetMailer ([out] IMail**mailer);〃声明所定义的构件的接口方法 } [即plet] class CMail {〃定义一个构件类 interface IMail ;〃声明该构件类实现该(Mail)的接口方法 } applet TMail { interface Imanager ; } 上述这段代码是对所调用的目标接口方法的定义、描述及需向目标接口方法传递
参数的定义。 (2)Mail.cpp ECode TMai 1: : Main ( ) { printf( "TMail: :Main() :current thread is 0x% x\n,,, CThread: :GetCurrent());
return N0ERR0R ; } ECode TMail: :GetMailer (Mail**ppMailer)
{ ECode ec = CMail::New(ppMailer); if (FAILED(ec))return ec ; printf ( "TMail: :GetMailer() :current thread is 0x% x\n,,, CThread: :GetCurrent());
return N0ERR0R ; } ECode CMail::SendMail(WString title, WString to,WString context) { ......//send mail printf ( "CMail: :SendMail () :current thread is 0x% x\n,,, CThread: :GetCurrent());
return N0ERR0R ; } 在对附图1的描述时所述的程序代码段(aa) , (bb)及(cc)所生成的打包参数的 数据结构、回调函数和夹壁墙函数在编译在时候会包含在该TMail. cpp主程序里,所以可 以认为它们是生成在主程序里的。 (3) Client, c卯〃 这是一个调用构件的客户端程序
...... IManager氺pIManager5
IMail*pMail ; TMail: :New(&pManager);〃创建一个TMail构件对象,TMail是一个Applet构 件 ......printf ( "In Caller Applet -current thread is Ox% x\n,,, CThread::GetCurrent());〃打印当前的线程句柄,每个运行时的线程句柄是唯一的;
pIManager-〉GetMailer (&pIMail);〃调用TMail的GetMailer方法,也就是调用 了一个Applet构件的方法,并获得一个Mail接口指针,其指向CMail构件对象,它是一个 具有Applet属性的构件对象;pIMail-〉SendMail (......);〃再调用CMail的SendMail方法,也就是调用一个
具有Applet属性的构件对象的方法;
...... (4) Console output〃运行程序后,控制台的输出 TMail: :Main() :current thread is 0x40001000〃Applet构件TMail的主线程 的线程句柄是0x40001000。这个线程同时也是它的回调线程。 In Caller Applet :current thread is 0x40002000〃调用A卯let的客户端程 序的线程的句柄是0x40002000。 TMail: :GetMailer0 :current thread is 0x40001000〃构件用户实现的 GetMailer方法运行时所在的线程的句柄是0x40001000。
CMail: :SendMail() -current thread is 0x40001000〃构件用户实现的 SendMail方法运行时所在的线程的句柄是0x40001000。 从上面的四个代码片断可以看出,被调用的GetMail方法和SendMail方法都是在 0x40001000这个线程里执行的,而这个线程是Applet的Mail线程,而与调用者是什么线程 没有关系。 因此可以确定,即便有多个外部线程同时调用Applet构件对象的方法,也不必考 虑多线程问题,因为所有调用都会进入消息队列,由消息线程逐个按序调用,具有线程安全 性。 对Applet实现的接口方法的调用一定是采用Applet线程模型的方式实现;对于 使用Applet属性关键字修饰的普通构件类的调用,也采用Applet线程模型完成。并且,由 哪个Applet创建的它,就由哪个Applet负责完成对它接口方法的调用请求。
如果Applet向外导出某个内部构件类对象也不必考虑多线程问题,或者破坏 Applet独立性,它可以使用Applet属性修饰该构件类。 对于调用Applet接口方法的一方来说,整个调用过程也是透明的,它仍然是同步 方式调用这些方法,当这些接口方法返回时就代表目标代码已执行完成,与调用其它构件 对象的接口方法并无不同。
权利要求
一种Applet线程模型,其特征在于,该Applet线程模型包括Applet构件和具有Applet属性的构件;属于该Applet构件的消息队列及回调线程;其中,Applet构件和具有Applet属性的构件都具备夹壁墙和一个Event对象;所述夹壁墙用来拦截和存放调用方构件的调用请求线程;所述Applet构件用于将调用请求打包成一个调用消息包,通过投递回调机制将该调用消息包投递到所述消息队列等待处理;所述回调线程用于当从消息队列接收到该调用消息包时,调用并执行所述目标接口方法,将执行结果返回给等待在所述构件夹墙壁中的调用请求线程,并激发该构件的Event对象;所述Event对象用于被回调线程激发后,通知被拦截在所述构件夹壁墙里进行等待的调用请求线程去获取执行结果以将该执行结果返回给调用方构件。
2. 如权利要求l所述的Applet线程模型,其特征在于,所述调用方构件为另一 Applet 构件,或另一具有Applet属性的构件,或为一外部构件。
3. 如权利要求1所述的Applet线程模型,其特征在于,所述回调线程调用并执行所述 目标接口方法是通过调用其所注册的回调函数,由该回调函数再调用并执行所述目标接口 方法。
4. 如权利要求3所述的Applet线程模型,其特征在于,所述回调函数是由编译工具自 动生成。
5. 如权利要求1所述的Applet线程模型,其特征在于,所述调用方构件的调用请求包 括调用参数、所调用构件的目标接口方法的信息。
6. —种基于Applet线程模型的调用构件的方法,其特征在于,该方法包括步骤 目标构件利用编译工具生成打包函数,该打包函数经编译生成DLL可执行文件; 创建该目标构件对象,调用方构件向该创建的目标构件对象发出调用请求; 拦截该调用请求并将其存放在目标构件的夹壁墙,由打包函数将该调用请求打包成一个调用消息包;目标构件对象利用投递回调事件的机制将上述调用消息包投递到其所属的消息队列中;当消息队列处理到该调用消息包时,回调线程从该消息队列接收该调用消息包; 该回调线程调用并执行所述的目标接口方法,将执行结果返回给等待在所述夹壁墙里的调用请求,并触发该目标构件对象的Event对象;该Event对象通知该调用请求去获取返回的执行结果,该调用请求将获取的执行结果返回给调用方构件。
7. 如权利要求6所述的调用构件的方法,其特征在于,所述目标构件为具有Applet属 性的普通构件类对象,所述之目标接口方法为Applet对象所实现的所有接口方法。
8. 如权利要求6所述的调用构件的方法,其特征在于,所述该回调线程调用并执行所 述的目标接口方法的步骤还包括该回调线程调用其注册的回调函数; 该回调函数调用及执行所述的目标接口方法;该回调函数将执行结果返回给等待在夹壁墙里的调用请求,并触发Event对象。
9. 如权利要求8所述的调用构件的方法,其特征在于,所述回调函数是由编译工具自 动生成的。
10. 如权利要求6所述的调用构件的方法,其特征在于,所述调用方构件的调用请求包 括调用参数、所调用构件的目标接口方法的信息。
全文摘要
本发明提供一种Applet线程模型及基于Applet线程模型的调用构件的方法。本发明利用构件所特有的夹壁墙技术,将所有针对Applet和具有Applet属性的构件对象的接口方法的调用都在夹壁墙中拦截,再将调用的参数和被调用的接口方法信息一起打包,通过投递回调事件的机制向被调用的Applet的消息队列中投递此次调用事件。此时调用线程进入等待状态,当被调用的Applet的消息循环处理到这次调用事件时,由Applet的回调线程执行目标接口方法,执行完成后再将结果返回给等待在夹壁墙的调用线程,再由它返回给调用方的Applet,由此完成一次调用。利用本发明可以解决Applet彼此调用时多线程问题,加强Applet之间的独立性,使得外界对Applet数据结构的访问和接口方法的调用只能通过Applet自己的线程来完成。
文档编号G06F9/46GK101770395SQ20081020805
公开日2010年7月7日 申请日期2008年12月29日 优先权日2008年12月29日
发明者宋世军, 陈榕 申请人:上海科泰世纪科技有限公司