2022年并发面向对象中的继承反常现象 .pdf
《2022年并发面向对象中的继承反常现象 .pdf》由会员分享,可在线阅读,更多相关《2022年并发面向对象中的继承反常现象 .pdf(10页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、并发面向对象中的继承反常现象1王生原杨良怀袁崇义杨萍Abstract.如果不考虑继承性, 并发性与对象技术的结合是很自然的。继承反常2(inheritance anomaly)现象是继承性和并发性不相容的主要原因之一。现阶段人们对继承反常现象的认识有许多模糊之处,出发点不尽相同,形式化的工作也很少。本文认为继承反常这一概念应有针对性,对不同的subtyping 关系应考虑其特有的渐增式继承(incremental inheritance )方法,这有利于把握继承反常现象的实质,而不被各类不同的观点所误导,同时也丰富了“在并发面向对象语言中应将inheritance 层次和 subtyping
2、层次区别对待”这一认识的内涵。在阐述基本观点后, 本文采用范畴论的术语对继承反常现象给出了一种形式化的定义,并对并发面向对象技术中继承性的建模提出相关的建议。Key Words:并发性;面向对象;继承反常;渐增式继承;范畴论1. 引言Inheritance(继承)是面向对象理论和技术中主要的概念之一。大多数人已认同这样的观点:一个程序设计语言,即使它支持对象(Object)和类( Class)的概念,如果不支持inheritance ,那么也不能称为是面向对象语言。继承是类之间的一种层次关系。Superclass 描述了同类subclass 的共性(泛化) ,而subclass 旨在继承其su
3、perclass 的这种共性,并扩展其特性(特化) 。继承是代码重用(Code Reuse)的重要途径之一。在一般的面向对象语言中,类层次自动对应了一种类型层次WZ88 ,这样, superclass和 subclass 之间的关系自然是一种supertype 和 subtype 之间的关系。 这种对应关系难免使人们在 inheritance 和 subtyping 之间产生模糊的认识。对于大多数顺序的面向对象语言来说,inheritance 和 subtyping 不加以区分几乎不会造成什么影响。但随着把并发性(concurrency)引入面向对象语言中(如Agha86 America90
4、Yonezawa90) ,人们发现inheritance和subtyping 之间并不容易协调,会出现所谓的继承反常(Inheritance Anomaly )现象 MY93。在并发面向对象语言(COOL)中,对象是很自然的并发单元。对象之间的通信和同步依靠消息传递, 而对象内部的并发活动则是通过共享变量方式进行通信和同步。无论对象之间还是对象内部的通信和同步,都和同步代码(Synchronization Code)有关。同步代码的主要作用是对对象内部及其与外界的接口的并发活动(如并发方法, 内部线程, 对共享变量的操作等)进行一种约束,即同步约束(Synchronization Constr
5、ains ) 。在 inheritance 层次中,方法(及属性)的增改很可能会破坏这种约束。换句话说,subclass 要兼容其superclass 的这种同步约束,很可能必须对相关的superclass 代码进行实质性修改,而不可能重用它们。这 种 现 象 在 MY93 中 被 首 次 称 为 继 承 反 常 。 在 此 之 前也 有 许 多 这 方 面 问 题 的 讨 论(America87KL89) ,目前仍很受关注(LLNW96CRR98) 。对于继承反常现象,目前的解决方案主要有两类:( 1)设计更强的同步机制MY93 ;(2)去掉同步原语Meseguer93LLNW96。但这些方
6、法只能有限地减小继承反常的危害,并不能从根本上解决问题。面对所遇到的困难,有人在考虑是不是存在概念上的误区BCC95 ,目前这仍是一个开放的话题。实际上,除了同步约束,继承反常现象也可能是由其它情况引起的(ABSB94 ) ,这说明继承反常应属inheritance 本身的特征。本文认为继承反常这一概念应有针对性,并发面向对象中的继承不能只狭隘地沿用顺序程序中渐增式的继承(incremental inheritance ) ,对不同的subtyping 关系应考虑其特有的渐1Supported by the National Natural Science Foundation of Chin
7、a under grant No. 69973003, and by the China NKBRSF (973) under grant G1999032706. 2又译:继承异常 . 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 10 页 - - - - - - - - - 增式继承方法。 这有利于把握继承反常现象的实质,而不被各类不同的观点所误导,同时也丰富了“在并发面向对象语言中应将inheritance 层次和 subtyping 层次区别对待”这一认识的内涵
8、。另一方面,不同背景和意义的“继承反常”足以使读者产生困惑。如有些工作称可以避开继承反常现象Meseguer93LLNW96,而另一些工作则认为继承反常是不可避免的CRR98 。究其原因主要是这方面的形式化工作很少,且不够全面。本文在上述观点的基础上,采用范畴论的术语对继承反常现象给出了一种形式化的定义。第 2 节通过经典实例使读者初步认识继承反常现象;第 3 节分析继承反常现象的实质及阐述本文理解这种现象的基本观点;第4 节用范畴论的术语形式地定义继承反常现象;第5节利用本文的定义对文献中出现的有关继承反常现象的典型情形进行了解释,并结合本文的观点,对并发面向对象技术中继承性的建模提出一些有
9、益的建议。2. 认识继承反常现象class Buffer int in= out=0, bufSIZE; method put() when (in = out + 1) out+; /rest code of get() ; class Buffer2: Buffer method get2() when (in = out + 2) out + = 2; /rest code of get2() ; class GBuffer: Buffer bool after_put = false; method gget() when (!after_put & (in = out + 1) ou
10、t+; after_put = false; /rest code of gget() ;method put() when (in = out + 1) out+; after_put = false; /rest code of get() ; class LockableBuffer: Buffer bool locked = false; method lock() when (!locked) locked = true ; method unlock() when (locked) locked = false ; method put() when (!locked & (in
11、= out + 1) out+; /rest code of get() ; 图 2.1 有界缓冲区类Buffer,及其子类Buffer2 、GBuffer 和 LockableBuffer 考虑图 2.1,类 Buffer 实现了一个有限缓冲区类型,可以并发地接受消息put 和 get。同步机制采用了“method guards ”方式,即为每一method 附加一个 guard 谓词,在图.1 中形如“ method method_name when guard” 。如果对类Buffer增加新方法gget 来构造子类GBuffer ,就不得不修改同步代码,从而方法 put 和 get 的代
12、码须重新定义。这里 gget 的行为同 get,但不可以紧跟在put 之后执行。同样,构造Buffer 的另一个子类LockableBuffer 也会引发同样的问题。这种“为获有效继承而必须对父类代码进行实质性修改的现象”就是所谓的继承反常(Inheritance Anomaly )MY93 。继承反常这一概念是针对某种特定的语言机制而言的。图2.1 中采用“ method guards”同步机制,类Buffer2 可以不加修改地继承Buffer 的方法 put 和 get(其中新方法get2 为每次从缓冲区取出个元素)。而语言ACT+ (一种基于Actor 的语言 KL89 )采用 Beha
13、vior Abstractions 机制,Buffer2 在继承 Buffer 时不可避免地要重新定义方法put 和 get,见图 2.2。下一节我们将讨论如何准确地理解继承反常现象,阐述本文的基本观点。3. 理解继承反常现象综合各种观点,要理解和解释继承反常现象,首先须正确区别inheritance层次和subtyping 层次及深刻领会二者的联系。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 10 页 - - - - - - - - - 3.1 区别 Inherit
14、ance和 Subtyping Inheritance 是类( class)之间的一种层次关系,而subtyping 是类型( type)之间的层次关系。 Type具有类型检测(type-checking)的语义,可以利用谓词来定义,即满足该谓词的所有对象都具有这种类型;而 class 具有实例创建的语义,是产生实例的模板 (templates) 。每个 class 对应一种特定的type,这种 type 的谓词是该class 模板的一种规范;但反过来每个 type 不一定都对应一个class,因为一种谓词未必可以成为某个模板的规范WZ88 。class b_buf: ACTOR / b_bu
15、f is an Actor int in, out, bufSIZE; behavior: empty = put; partial = put, get; full =get; public: void b_buf() in = out = 0; become empty; void put() in+; / store an item if (in = out + size) become full; else become partial; void get() out+; / remove an itemif (in = out) become empty; else become p
16、artial; class b_buf2: b_buf / b_buf2 is a subclass of b-buf behavior: x_empty = put; x_one = put, get; x_partial = put, get, get2; x_ full = get, get2; / x_empty renames empty, x_partial redefines partial; x_full redefines full; public: void b_buf() in = out = 0; become x_empty; void get2() out += 2
17、; / definiton of get2if (in = out) become x_empty; else if (in = out + 1) become x_one; else become x_partial; / The following re-defines the methods in b-buf. void put() in+; if (in = out + size) become x_full; else if (in = out + 1) become x_one; else become x_partial; void get() out+; if (in = ou
18、t) become x_empty; else if (in = out + 1) become x_one; else become x_partial; 图 2.2 用 ACT+ 描述的有界缓冲区类b_buf,及其子类b_buf2 在面向对象语言中,class 是一个语法单位,它包含若干属性及方法的说明,每个class的实例共享这些说明。Type可看作是共有某些外部可观察(externaly observable )行为特性的实例的集合,即type 实际上是一种对其元素的行为规范(对应以上所述的“一种谓词”America91 ) ,如抽象数据类型(abstract data types )
19、是较常用的行为规范技术。Subtype 是根据谓词来修改,而subclass 是根据模板来修改。Inheritance 属于后者,而subtyping 属于前者。Inheritance提供了一种类之间共享代码的机制。通过inheritance ,subclass 可重用( reuse)superclass的代码。 P.America 指出 America91 ,通过 inheritance 进行代码共享不一定自动带来行为的特化(如引入或修改的新的属性和方法可能破坏原有的属性和方法赖以发挥作用的不变量), 并认为应该用subtyping 而不是 inheritance 来特指行为特化。本文中su
20、btyping 的概念满足可替换性原则(Principle of Substitutability)WZ88 :An instance of a subtype can always be used in any context in which an instance of a supertype was expected.综上所述, inheritance 是在代码层次上作修改,而subtyping 是在语义层次上作修改。前名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,
21、共 10 页 - - - - - - - - - 者是代码共享的一种重要途径,但不能保证subclass 能够继承 superclass 的行为;后者要求subtype 保持 supertype 的某种外部可观察行为(或语义行为),在规范一级共享,同代码没有关系。 Inheritance 层次关系可以理解为“is_similar_to ” (或“ like” )的关系,而将“is_a”关系用在理解subtyping 层次关系更妥 (可以描述成 “从某种语义行为来看,B 是 A 的 subtype?每个 B 的实例 is_a A 的实例”)。3.2 渐增式继承Subtyping 要求 subty
22、pe保持 supertype的某种行为(可看作是一种不变量,比如同步约束) ,subclass 在增加新的属性或方法时,为了避免破坏这种不变量,难免要对从superclass 继承下来的代码进行扩展或修改。而这种扩展或修改很可能是重大的或实质性的,结果使得inheritance 层次从代码共享的角度看变得没有意义。这便是继承反常的(非形式)含义。那么什么样的扩展或修改算是重大的或实质性的呢?这是比较含糊的说法,以至于多种关于继承反常的说法使读者产生误解。如有些工作称可以避开继承反常 Meseguer93 LLNW96,而另一些工作则认为继承反常是不可避免的CRR98 。CRR98 在 inhe
23、ritance必须是渐增式的假设下,给继承反常下了一个形式化的定义。按此定义, 先前人们声称对继承反常问题的解决都是部分的,即没有任何一种解决方案是彻底的。这是一个极端的定义,它所规定的渐增式继承不允许对继承下来的代码作任何形式的修改。为了对人们在解决这个问题上的努力有所区别,同时兼顾到不同的语言特征,我们有必要对“渐增式继承”采取较为灵活的解释。首先,对于不同的并发面向对象语言(COOL) ,渐增式继承的含义应该有所不同。如对基于 Petri 网的 COOL(Lakos95 BCC95 ) ,将子网( Subnets)关系看作渐增式继承是恰当的,没必要苛求子类网中新增的部分与从父类继承的部分
24、不相交。参考图3.1,N0是 N1、N2和 N3的子网, N1、N2和 N3渐增继承了N0。然而,这种子网关系的继承只强调了网结构(代码)的重用,而未顾及行为的重用。在顺序的面向对象程序设计中,代码的重用是inheritance 的一个主要目的, 而行为的重用几乎可以不去考虑, 因为方法之间最多只有调用关系,没有同步代码带来的同步约束,其它约束(如实时方面的约束)只是在特定情况下才考虑。对于并发面向对象的程序,情况就不同了,代码的重用固然是inheritance 的一个重要目的, 但行为的重用更突显其重要地位,也成为问题的焦点。行为的重用在COOL 中是由 subtyping 关系体现的。从前
25、面章节的讨论可知,代码重用和行为重用之间的不兼容是产生继承反常的根源。因此,为了兼顾两种重用,在COOL 中严格区分inheritance 层次和 subtyping 层次成为一种趋势,许多语言设计了这样的机制,如CO-OPN/2 Biberstein97 。甚至我们认为,为方便不同的应用,一个COOL 支持多个不同的subtyping 层次是很有必要的。实际上,在多数(顺序的和并发的)面向对象语言中,至少有一个蕴涵的subtyping 层次:即supertype 的实例可接受什么消息,在其subtype 的实例中也可接受同样的消息(这是多态性的一种)。图3.1 ( N 1 ptN0,N 2p
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年并发面向对象中的继承反常现象 2022 并发 面向 对象 中的 继承 反常 现象
限制150内