專利名稱::具有協(xié)作對(duì)象的修改后的計(jì)算機(jī)架構(gòu)的制作方法
技術(shù)領(lǐng)域:
:本發(fā)明涉及計(jì)算機(jī),具體而言,涉及一種修改的計(jì)算機(jī)架構(gòu),其使應(yīng)用程序能夠在經(jīng)由通信網(wǎng)絡(luò)互連的多個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行。
背景技術(shù):
:自從計(jì)算機(jī)及計(jì)算出現(xiàn)以來,所編寫的計(jì)算機(jī)軟件是在單個(gè)機(jī)器上運(yùn)行的。如圖1所示,所示的單個(gè)現(xiàn)有技術(shù)機(jī)器ι包括經(jīng)由總線4連接至存儲(chǔ)器3的中央處理單元CPU2。連接至總線4的還有單個(gè)機(jī)器1的其他功能單元,如屏幕5、鍵盤6和鼠標(biāo)7。對(duì)該機(jī)器1性能的基本限制在于數(shù)據(jù)由CPU2來處理,而這些處理結(jié)果必須通過總線4來傳送。總線4經(jīng)受很多問題,包括由想要獲取對(duì)總線的訪問的單元所形成的所謂總線“隊(duì)列”、競(jìng)爭(zhēng)問題等。在某種程度上,這些問題可通過各種策略來緩解,所述策略包括高速緩沖存儲(chǔ)器,但是,這樣的策略沒有例外地會(huì)增加機(jī)器1的管理開銷。自然,多年來,為了改善機(jī)器性能,人們進(jìn)行了各種嘗試。一種方法是使用對(duì)稱的多個(gè)處理器。該現(xiàn)有技術(shù)方法已用于所謂的“超級(jí)”計(jì)算機(jī)中,如圖2中示意性示出的。這里,多個(gè)CPU12連接至全局存儲(chǔ)器13。而在CPU12和存儲(chǔ)器13間的通信中也出現(xiàn)了瓶頸。該過程被稱作“單系統(tǒng)映像”。僅有一個(gè)應(yīng)用以及用于該應(yīng)用的分布在全局存儲(chǔ)器上的存儲(chǔ)器的一個(gè)完整拷貝。該單個(gè)應(yīng)用可完全透明地從任何存儲(chǔ)器位置讀取或?qū)懭肴魏未鎯?chǔ)器位置(即共享)。當(dāng)存在經(jīng)由網(wǎng)絡(luò)互連的多個(gè)這樣的機(jī)器時(shí),這是通過利用針對(duì)單個(gè)機(jī)器編寫的單個(gè)應(yīng)用并將所需存儲(chǔ)器資源分割成多個(gè)部分來實(shí)現(xiàn)的。然后,這些部分分布在多個(gè)計(jì)算機(jī)上,以形成可由所有CPU12訪問的全局存儲(chǔ)器13。該過程依賴于對(duì)運(yùn)行的單個(gè)應(yīng)用程序遮蔽或隱藏所述的存儲(chǔ)器分割。當(dāng)一個(gè)機(jī)器上的一個(gè)CPU必須(經(jīng)由網(wǎng)絡(luò))訪問物理上位于不同機(jī)器中的存儲(chǔ)器位置時(shí),性能會(huì)劣化。盡管超級(jí)計(jì)算機(jī)已在獲取高計(jì)算速率方面在技術(shù)上取得了成功,但是其在商業(yè)上是不成功的,因?yàn)槠涔逃械膹?fù)雜性使得其制造和管理極其昂貴。特別是,單系統(tǒng)映像的概念從未能夠應(yīng)用于“日用”(大量生產(chǎn)的)計(jì)算機(jī)和網(wǎng)絡(luò)。特別是,單系統(tǒng)映像的概念僅僅實(shí)際應(yīng)用于經(jīng)由很快速的(因此很昂貴的)網(wǎng)絡(luò)互連的很快速的(同樣昂貴的)計(jì)算機(jī)上。通過使用多個(gè)機(jī)器來增加計(jì)算機(jī)能力的另一可能性來自現(xiàn)有技術(shù)的分布式計(jì)算概念,如圖3中示意性所示。在該已知設(shè)置中,單個(gè)應(yīng)用程序(Ap)由其作者(或熟悉該應(yīng)用程序的另一程序員)分割成多個(gè)離散任務(wù),以便在例如3個(gè)機(jī)器上運(yùn)行,在圖3中,η為整數(shù)3。這里的意圖是,機(jī)器Ml...Μ3的每個(gè)運(yùn)行整個(gè)應(yīng)用的不同的三分之一,且意圖是使施加于各機(jī)器的負(fù)載大體相等。所述機(jī)器經(jīng)由網(wǎng)絡(luò)14來通信,所述網(wǎng)絡(luò)14可以各種形式來提供,如通信鏈路、互聯(lián)網(wǎng)、內(nèi)聯(lián)網(wǎng)、局域網(wǎng)等。這種網(wǎng)絡(luò)14的運(yùn)行速度一般比各機(jī)器Ml、6M2等的每個(gè)的總線4的運(yùn)行速度慢一個(gè)量級(jí)。分布式計(jì)算具有多個(gè)缺點(diǎn)。第一,分割應(yīng)用是一項(xiàng)困難的工作,而且必須人工完成。第二,網(wǎng)絡(luò)14上的通信數(shù)據(jù)、部分結(jié)果、結(jié)果等是一種管理開銷。第三,分割的需要使利用更多機(jī)器來擴(kuò)展變得極其困難,因?yàn)橐逊指畛衫?部分的應(yīng)用不能在4個(gè)機(jī)器上很好地運(yùn)行。第四,在其中一個(gè)機(jī)器不能工作時(shí),會(huì)實(shí)質(zhì)上降低整個(gè)系統(tǒng)的總體性能。另一現(xiàn)有技術(shù)設(shè)置已知為通過“簇(cluster)”的網(wǎng)絡(luò)計(jì)算,如圖4中示意性所示。在該方法中,整個(gè)應(yīng)用被載入每個(gè)機(jī)器Ml、M2.....Mn上。每個(gè)機(jī)器都與公共數(shù)據(jù)庫(kù)通信,但不與其他機(jī)器直接通信。盡管每個(gè)機(jī)器運(yùn)行同一應(yīng)用,但是每個(gè)機(jī)器進(jìn)行不同的“工作,,并僅使用其自己的存儲(chǔ)器。這有點(diǎn)類似于多個(gè)窗口每個(gè)均向公眾出售火車票。該方法確實(shí)可行、可升級(jí),而主要具有的缺點(diǎn)是難以管理網(wǎng)絡(luò)。在計(jì)算機(jī)語言如JAVA和MICROSOFT.NET中,有程序員應(yīng)對(duì)的兩種主要類型的結(jié)構(gòu)。在JAVA語言中,它們稱作對(duì)象和類。每次創(chuàng)建對(duì)象時(shí),均有稱作“<init>”的初始化例程運(yùn)行。同樣,每次加載類時(shí),均有稱作“<clinit>”的初始化例程運(yùn)行。其他語言使用不同的術(shù)語,但利用相似的概念。然而,一旦不再需要對(duì)象或類時(shí),卻沒有相當(dāng)?shù)摹扒謇怼被騽h除例程來刪除對(duì)象或類。相反地,該“清理”以后臺(tái)的方式不引人注意地發(fā)生。另外,在任何計(jì)算機(jī)環(huán)境中都需要獲取和釋放鎖定(lock),以便能夠使用這樣的資產(chǎn)、資源或結(jié)構(gòu),而避免應(yīng)用程序的不同部分試圖同時(shí)使用同一資源。在JAVA環(huán)境中,這稱作同步。在JAVA中,這是通過“monitorenter”和“monitorexit”指令或例程來實(shí)現(xiàn)的。其他語言使用不同的術(shù)語,但利用相似的概念。
發(fā)明內(nèi)容本發(fā)明公開了一種計(jì)算環(huán)境,其中一個(gè)應(yīng)用程序同時(shí)在多個(gè)計(jì)算機(jī)上運(yùn)行。在這種環(huán)境中,需要保證上述初始化、清理和同步過程在所有機(jī)器上以一致而協(xié)作的方式來運(yùn)行。該協(xié)作目的即是本發(fā)明的起源。根據(jù)本發(fā)明的第一方面,公開了一種多計(jì)算機(jī)系統(tǒng),該多計(jì)算機(jī)系統(tǒng)具有各被編寫為僅在單個(gè)計(jì)算機(jī)上運(yùn)行但卻在經(jīng)由通信網(wǎng)絡(luò)互連的多個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行的至少一個(gè)應(yīng)用程序,其中創(chuàng)建了同樣多個(gè)基本相同的對(duì)象,每個(gè)對(duì)象在對(duì)應(yīng)的計(jì)算機(jī)中,且每個(gè)具有基本相同的名稱,其中所述相同命名的對(duì)象每個(gè)的初始內(nèi)容是基本上相同的,其中,當(dāng)所述多個(gè)計(jì)算機(jī)的每個(gè)不再需要引用其對(duì)應(yīng)的對(duì)象時(shí),所有所述相同的對(duì)象被全體刪除,并且其中,所述系統(tǒng)包括可應(yīng)用于所有所述計(jì)算機(jī)的鎖定裝置,其中想要利用其中的被命名的對(duì)象的任一計(jì)算機(jī)從所述鎖定裝置獲取授權(quán)鎖定,所述授權(quán)鎖定允許所述利用,并防止所有其他計(jì)算機(jī)利用它們對(duì)應(yīng)的被命名的對(duì)象,直到所述授權(quán)鎖定被放棄。根據(jù)本發(fā)明的第二方面,公開了一種在多個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行至少一個(gè)各被編寫為僅在單個(gè)計(jì)算機(jī)上運(yùn)行的應(yīng)用程序的方法,所述計(jì)算機(jī)借助于通信網(wǎng)絡(luò)來互連,所述方法包括下列步驟i)創(chuàng)建同樣多個(gè)基本相同的對(duì)象,每個(gè)對(duì)象在對(duì)應(yīng)的計(jì)算機(jī)中,且每個(gè)具有基本相同的名稱,ii)創(chuàng)建所述的相同命名的對(duì)象的每個(gè)的初始內(nèi)容,所述初始內(nèi)容基本上相同,iii)當(dāng)所有所述多個(gè)計(jì)算機(jī)不再需要引用其對(duì)應(yīng)的對(duì)象時(shí),全體刪除所有所述的相同對(duì)象,以及iv)要求其中想要利用命名對(duì)象的所述計(jì)算機(jī)中的任何一個(gè)去獲取授權(quán)鎖定,該授權(quán)鎖定允許所述利用,并防止所有其他計(jì)算機(jī)利用它們的對(duì)應(yīng)的被命名的對(duì)象,直到所述授權(quán)鎖定被放棄。根據(jù)本發(fā)明的一方面,公開了一種多計(jì)算機(jī)系統(tǒng),具有同時(shí)運(yùn)行在多個(gè)計(jì)算機(jī)上的至少一個(gè)應(yīng)用程序,其中所述多個(gè)計(jì)算機(jī)通過通信網(wǎng)絡(luò)來互連,其中創(chuàng)建同樣多個(gè)基本上相同的對(duì)象,每個(gè)所述對(duì)象在對(duì)應(yīng)的計(jì)算機(jī)中且各具有基本上相同的名稱,其中每個(gè)所述的相同命名的對(duì)象的初始內(nèi)容是基本上相同的,其中當(dāng)所述多個(gè)計(jì)算機(jī)的每個(gè)不再需要引用其對(duì)應(yīng)的對(duì)象時(shí),所有所述相同的對(duì)象被全體刪除,并且其中所述系統(tǒng)包括可應(yīng)用于所有所述計(jì)算機(jī)的鎖定裝置,其中想要利用其中所命名的對(duì)象的任何計(jì)算機(jī)從所述鎖定裝置獲取授權(quán)鎖定,所述鎖定裝置允許所述利用,并防止所有其他計(jì)算機(jī)利用其對(duì)應(yīng)的所命名的對(duì)象,直到所述授權(quán)鎖定被放棄。其中,所述鎖定裝置包括獲取鎖定例程和釋放鎖定例程,且兩個(gè)例程均包括在對(duì)所述應(yīng)用程序的修改中,其中所述應(yīng)用程序運(yùn)行在所有所述計(jì)算機(jī)上。其中,所述鎖定裝置進(jìn)一步包括共享表,該共享表列出由任何所述計(jì)算機(jī)所使用的所述命名的對(duì)象、每個(gè)所述對(duì)象的鎖定狀態(tài)以及任何未決的鎖定獲取的隊(duì)列。其中,所述鎖定裝置位于不運(yùn)行所述應(yīng)用程序并連接到所述通信網(wǎng)絡(luò)的附加計(jì)算機(jī)內(nèi)。其中,每個(gè)所述計(jì)算機(jī)都包括分布式運(yùn)行時(shí)間裝置,其中每個(gè)所述計(jì)算機(jī)的分布式運(yùn)行時(shí)間裝置能夠與所有其他計(jì)算機(jī)通信,由此如果運(yùn)行在所述計(jì)算機(jī)之一上的所述應(yīng)用程序的部分在該計(jì)算機(jī)中創(chuàng)建對(duì)象,則所創(chuàng)建的對(duì)象由所述的一個(gè)計(jì)算機(jī)的分布式運(yùn)行時(shí)間裝置傳播到所有其他計(jì)算機(jī)。其中,每個(gè)所述計(jì)算機(jī)都包括分布式運(yùn)行時(shí)間裝置,其中每個(gè)所述計(jì)算機(jī)的分布式運(yùn)行時(shí)間裝置能夠與所有其他計(jì)算機(jī)通信,由此如果運(yùn)行在所述計(jì)算機(jī)之一上的所述應(yīng)用程序的部分不再需要引用該計(jì)算機(jī)中的對(duì)象,則不被引用的對(duì)象的標(biāo)識(shí)由所述的一個(gè)計(jì)算機(jī)的分布式運(yùn)行時(shí)間裝置傳送至可由所有其他計(jì)算機(jī)訪問的共享表。其中,通過插入初始化例程在加載之前、期間或之后對(duì)每個(gè)所述應(yīng)用程序進(jìn)行修改,以對(duì)所述應(yīng)用程序在其處創(chuàng)建對(duì)象的每個(gè)實(shí)例進(jìn)行修改,所述初始化例程將一個(gè)計(jì)算機(jī)新創(chuàng)建的每個(gè)對(duì)象傳播到所有所述其他計(jì)算機(jī)。其中,所述應(yīng)用程序是根據(jù)從下列過程構(gòu)成的組中所選出的過程來修改的加載時(shí)的重新編譯、加載前的預(yù)編譯、加載前的編譯、剛好適時(shí)的編譯、在加載后且在應(yīng)用程序相關(guān)部分執(zhí)行之前的重新編譯。其中,所述被修改的應(yīng)用程序根據(jù)從下列構(gòu)成的組中所選出的過程被傳送到所有所述計(jì)算機(jī)主/從傳送、分支傳送和級(jí)聯(lián)傳送。其中,分配給所述應(yīng)用程序或每個(gè)所述應(yīng)用程序的本地存儲(chǔ)器容量基本上相同,且對(duì)所述應(yīng)用程序或每個(gè)所述應(yīng)用程序可用的總存儲(chǔ)器容量是所述的所分配的存儲(chǔ)器容量。其中,所有所述計(jì)算機(jī)包括分布式更新裝置,每個(gè)所述分布式更新裝置以明顯小8于本地存儲(chǔ)器讀取速率的數(shù)據(jù)傳送速率經(jīng)由所述通信鏈路來通信。其中,所述計(jì)算機(jī)的至少一些由不同制造商制造和/或具有不同的操作系統(tǒng)。根據(jù)本發(fā)明的另一方面,公開一種在多個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行至少一個(gè)應(yīng)用程序的方法,所述計(jì)算機(jī)借助于通信網(wǎng)絡(luò)來互連,所述方法包括下列步驟(i)創(chuàng)建同樣多個(gè)基本上相同的對(duì)象,每個(gè)所述對(duì)象在對(duì)應(yīng)的計(jì)算機(jī)中且具有基本上相同的名稱,(ii)創(chuàng)建每個(gè)所述的相同命名的對(duì)象的基本上相同的初始內(nèi)容,(iii)當(dāng)所有所述多個(gè)計(jì)算機(jī)不再需要引用其對(duì)應(yīng)的對(duì)象時(shí),所有所述的相同對(duì)象被全體刪除,以及(iv)要求想要利用其中所命名的對(duì)象的任何所述計(jì)算機(jī)獲取授權(quán)鎖定,所述授權(quán)鎖定允許所述利用,并防止所有其他計(jì)算機(jī)利用其對(duì)應(yīng)的被命名的對(duì)象,直到所述授權(quán)鎖定被放棄。根據(jù)本發(fā)明一個(gè)實(shí)施例的該方法進(jìn)一步包括下列步驟(V)如果運(yùn)行在所述計(jì)算機(jī)之一上的所述應(yīng)用程序的部分在該計(jì)算機(jī)中創(chuàng)建對(duì)象,則將所創(chuàng)建的對(duì)象經(jīng)由所述通信網(wǎng)絡(luò)傳播到所有其他計(jì)算機(jī)。根據(jù)本發(fā)明一個(gè)實(shí)施例的該方法進(jìn)一步包括下列步驟(vi)通過插入初始化例程,在加載之前、期間或之后對(duì)每個(gè)所述應(yīng)用程序進(jìn)行修改,以對(duì)所述應(yīng)用程序在其處創(chuàng)建對(duì)象的每個(gè)實(shí)例進(jìn)行修改,所述初始化例程將一個(gè)計(jì)算機(jī)創(chuàng)建的每個(gè)對(duì)象都傳播到所有所述其他計(jì)算機(jī)。根據(jù)本發(fā)明一個(gè)實(shí)施例的該方法進(jìn)一步包括下列步驟(Vii)為每個(gè)所述計(jì)算機(jī)提供分布式運(yùn)行時(shí)間裝置,以經(jīng)由所述通信網(wǎng)絡(luò)在所述計(jì)算機(jī)之間通信。根據(jù)本發(fā)明一個(gè)實(shí)施例的該方法進(jìn)一步包括下列步驟(Viii)提供可由每個(gè)所述分布式運(yùn)行時(shí)間裝置訪問的共享表,并且其中存儲(chǔ)不再要求訪問對(duì)象的任何計(jì)算機(jī)的標(biāo)識(shí)、連同該對(duì)象的標(biāo)識(shí)。根據(jù)本發(fā)明一個(gè)實(shí)施例的該方法進(jìn)一步包括下列步驟(ix)使計(jì)數(shù)器裝置與所述共享表關(guān)聯(lián),所述計(jì)數(shù)器裝置存儲(chǔ)對(duì)不再要求訪問所述對(duì)象的所述計(jì)算機(jī)的數(shù)量的計(jì)數(shù)。根據(jù)本發(fā)明一個(gè)實(shí)施例的該方法進(jìn)一步包括下列步驟(x)提供附加計(jì)算機(jī),在所述附加計(jì)算機(jī)上不運(yùn)行所述的共享程序,并且所述附加計(jì)算機(jī)容納所述共享表和計(jì)數(shù)器,所述附加計(jì)算機(jī)連接到所述通信網(wǎng)絡(luò)。根據(jù)本發(fā)明一個(gè)實(shí)施例的該方法進(jìn)一步包括下列步驟(Xi)提供可由每個(gè)所述分布式運(yùn)行時(shí)間裝置訪問的共享表,并且其中存儲(chǔ)當(dāng)前須訪問對(duì)象的任何計(jì)算機(jī)的標(biāo)識(shí)、連同該對(duì)象的標(biāo)識(shí)。根據(jù)本發(fā)明一個(gè)實(shí)施例的該方法進(jìn)一步包括下列步驟(Xii)使計(jì)數(shù)器裝置與所述共享表關(guān)聯(lián),所述計(jì)數(shù)器裝置存儲(chǔ)對(duì)尋求對(duì)所述對(duì)象的訪問的所述計(jì)算機(jī)的數(shù)量的計(jì)數(shù)。根據(jù)本發(fā)明一個(gè)實(shí)施例的該方法進(jìn)一步包括下列步驟(Xiii)提供附加計(jì)算機(jī),所述的共享程序不在所述附加計(jì)算機(jī)上運(yùn)行,并且所述附加計(jì)算機(jī)容納所述共享表和計(jì)數(shù)器,所述附加計(jì)算機(jī)連接到所述通信網(wǎng)絡(luò)。根據(jù)本發(fā)明的再一方面,公開了多個(gè)計(jì)算機(jī),經(jīng)由通信網(wǎng)絡(luò)互連,并可操作以保證對(duì)在所述多個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行的應(yīng)用程序的一致的初始化,所述多個(gè)計(jì)算機(jī)被編程來執(zhí)行如上所述的方法。根據(jù)本發(fā)明的一個(gè)方面,公開了一種多計(jì)算機(jī)系統(tǒng),所述多計(jì)算機(jī)系統(tǒng)具有至少一個(gè)應(yīng)用程序,所述應(yīng)用程序在通過通信網(wǎng)絡(luò)互連的多個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行,其中所述應(yīng)用程序的不同部分基本上同時(shí)在所述多個(gè)計(jì)算機(jī)中不同的計(jì)算機(jī)上執(zhí)行,其中對(duì)于每個(gè)所述部分,創(chuàng)建同樣多個(gè)基本上相同的對(duì)象,每個(gè)所述對(duì)象在對(duì)應(yīng)的計(jì)算機(jī)中,且其中每個(gè)所述計(jì)算機(jī)的所有讀請(qǐng)求僅從讀在請(qǐng)求計(jì)算機(jī)中創(chuàng)建的對(duì)象來滿足。根據(jù)本發(fā)明的另一個(gè)方面,公開了一種在多個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行至少一個(gè)應(yīng)用程序的方法,所述計(jì)算機(jī)借助于通信網(wǎng)絡(luò)來互連,所述方法包括以下步驟(i)在所述計(jì)算機(jī)中的不同計(jì)算機(jī)上執(zhí)行所述應(yīng)用程序的不同部分,以及對(duì)于每個(gè)所述部分,創(chuàng)建同樣多個(gè)基本上相同的對(duì)象,所述對(duì)象每個(gè)在對(duì)應(yīng)的計(jì)算機(jī)中;以及(ii)通過僅從讀在請(qǐng)求計(jì)算機(jī)中創(chuàng)建的對(duì)象來滿足每個(gè)所述計(jì)算機(jī)的所有讀請(qǐng)求。根據(jù)本發(fā)明的再個(gè)方面,公開了一種單個(gè)計(jì)算機(jī),被布置為與至少一個(gè)其他同樣的計(jì)算機(jī)合作以形成上面所述的多計(jì)算機(jī)系統(tǒng)。根據(jù)本發(fā)明的其他方面,公開了一種計(jì)算機(jī)程序產(chǎn)品,該計(jì)算機(jī)程序產(chǎn)品包括一組程序指令,該程序指令存儲(chǔ)于存儲(chǔ)介質(zhì)中,并可操作以允許多個(gè)計(jì)算機(jī)執(zhí)行上述方法。下面將參考附圖來說明本發(fā)明的實(shí)施例,在附圖中圖1示意性示出了傳統(tǒng)計(jì)算機(jī)的內(nèi)部架構(gòu),圖2示意性示出了已知的對(duì)稱多處理器的內(nèi)部架構(gòu),圖3示意性示出了現(xiàn)有技術(shù)的分布式計(jì)算,圖4示意性示出了現(xiàn)有技術(shù)的利用簇的網(wǎng)絡(luò)計(jì)算,圖5是根據(jù)本發(fā)明第一實(shí)施例的多個(gè)機(jī)器運(yùn)行同一應(yīng)用程序的示意性框圖,圖6示意性示出了設(shè)置用于運(yùn)行JAVA代碼并由此構(gòu)成JAVA虛擬機(jī)的現(xiàn)有技術(shù)計(jì)算機(jī),圖7與圖6相似,但示出了根據(jù)本發(fā)明優(yōu)選實(shí)施例的對(duì)代碼的初始加載,圖8與圖5相似,但示出了各以圖7所示的方式來運(yùn)行JAVA代碼的多個(gè)計(jì)算機(jī)的互連,圖9是在將同一應(yīng)用加載到網(wǎng)絡(luò)中每個(gè)機(jī)器上的期間所遵循的過程的流程圖,圖10的流程圖示出了與圖9的過程相似的修改的過程,圖11示意性示出了利用存儲(chǔ)器更新的第一實(shí)施例在圖8的機(jī)器上執(zhí)行多個(gè)線程處理。圖12的示意圖與圖11相似,但示出了另一實(shí)施例,圖13示出了用于圖8的計(jì)算機(jī)的多線程存儲(chǔ)器更新,圖14示意性示出了設(shè)置用于以JAVA代碼運(yùn)行并由此構(gòu)成JAVA虛擬機(jī)的現(xiàn)有技術(shù)計(jì)算機(jī),圖15示意性示出了運(yùn)行應(yīng)用程序并由附加的服務(wù)器機(jī)器X來提供服務(wù)的η個(gè)機(jī)器,圖16的流程圖示出了初始化例程的修改,圖17的流程圖示出了初始化例程的繼續(xù)或中止,10圖18的流程圖示出了發(fā)送到服務(wù)器機(jī)器X的問詢,圖19是服務(wù)器機(jī)器X對(duì)圖18的請(qǐng)求作出響應(yīng)的流程圖,圖20的流程圖示出了針對(duì)<clinit>指令的修改的初始化例程,圖21的流程圖示出了針對(duì)<init>指令的修改的初始化例程,圖22的流程圖示出了“清理”或終結(jié)化例程的修改,圖23的流程圖示出了終結(jié)化例程的繼續(xù)或中止,圖24的流程圖示出了發(fā)送到服務(wù)器機(jī)器X的問詢,圖25是服務(wù)器機(jī)器X對(duì)圖24的請(qǐng)求作出響應(yīng)的流程圖,圖26的流程圖示出了monitorenter和exit例程的修改,圖27的流程圖示出了處理機(jī)器在請(qǐng)求獲取鎖定中所遵循的過程,圖28的流程圖示出了請(qǐng)求釋放鎖定,圖29是服務(wù)器機(jī)器X對(duì)圖27的請(qǐng)求作出響應(yīng)的流程圖,圖30是服務(wù)器機(jī)器X對(duì)圖28的請(qǐng)求作出響應(yīng)的流程圖,圖31示意性示出了互連以同時(shí)運(yùn)行多個(gè)應(yīng)用的兩個(gè)膝上計(jì)算機(jī),其中兩個(gè)應(yīng)用在單個(gè)計(jì)算機(jī)上運(yùn)行,圖32的視圖與圖31相似,但示出了其中在每個(gè)計(jì)算機(jī)上運(yùn)行一個(gè)應(yīng)用的圖31的裝置,圖33的視圖與圖31和32相似,但示出了其中兩個(gè)應(yīng)用同時(shí)在兩個(gè)計(jì)算機(jī)上運(yùn)行的圖31的裝置。本說明書包括附件A、B、C和D,這些附件提供了實(shí)際程序的片段,所述程序的片段可實(shí)施所述實(shí)施例的各方面。附件A涉及字段,而附件B涉及初始化。附件C涉及終結(jié)化。附件D涉及同步。具體實(shí)施例方式結(jié)合圖5,根據(jù)本發(fā)明的一個(gè)優(yōu)選實(shí)施例,單個(gè)應(yīng)用程序50可在經(jīng)由網(wǎng)絡(luò)53通信的多個(gè)機(jī)器Ml、M2...Mn上同時(shí)運(yùn)行。如下文中將變得明顯的,機(jī)器M1、M2...Mn中的每個(gè)在每個(gè)機(jī)器Ml、M2...Mn上運(yùn)行同一應(yīng)用程序50,因此所有機(jī)器Ml、M2...Mn均具有相同的應(yīng)用代碼和數(shù)據(jù)50。同樣,機(jī)器Ml、M2...Mn中的每個(gè)在每個(gè)機(jī)器Ml、M2...Mn上運(yùn)行相同的(或基本上相同的)修改器51,因此所有機(jī)器Ml、M2...Mn均具有相同的(或基本上相同的)修改器51,其中機(jī)器M2的修改器被指定為51/2。此外,在應(yīng)用50被加載于每個(gè)機(jī)器Ml、M2...Mn上的過程中,或在應(yīng)用50在每個(gè)機(jī)器Ml、M2...Mn上被執(zhí)行之前,每個(gè)應(yīng)用50已由對(duì)應(yīng)的修改器51根據(jù)相同的規(guī)則(或基本上相同的規(guī)則,因?yàn)樵诿總€(gè)修改器51/1...51/n內(nèi)允許小的優(yōu)化改變)進(jìn)行了修改。作為上述設(shè)置的結(jié)果,如果機(jī)器Ml、M2...Mn中的每個(gè)都具有例如IOMB的共享存儲(chǔ)器容量,那么對(duì)每個(gè)應(yīng)用50可用的總共享存儲(chǔ)器不是如可能所預(yù)期的那樣為IOnMB,而是僅僅10MB。然而,這如何導(dǎo)致改善的運(yùn)行將在下文中變得明顯。自然,機(jī)器Ml、M2...Mn中的每個(gè)具有非共享的存儲(chǔ)器容量。機(jī)器Ml、M2...Mn中的非共享存儲(chǔ)器容量一般近似相等,但不一定必須如此。從現(xiàn)有技術(shù)已知,通過創(chuàng)建圖6中示意性示出的虛擬機(jī)以特定應(yīng)用語言來運(yùn)行機(jī)11器(由不同制造商之一生產(chǎn),并具有以各種不同的語言之一來運(yùn)行的操作系統(tǒng))。圖6的現(xiàn)有技術(shù)設(shè)置具有以Java語言編寫并在Java虛擬機(jī)61內(nèi)執(zhí)行的應(yīng)用50的形式。因此,當(dāng)應(yīng)用想要采用的語言是語言JAVA時(shí),能夠運(yùn)行JAVA代碼的JAVA虛擬機(jī)就被創(chuàng)建,而不管機(jī)器制造商及機(jī)器內(nèi)部細(xì)節(jié)。更多細(xì)節(jié)參見美國(guó)SUNMicrosystemsInc.的Τ.Lindholm&F.Yellin的“TheJAVAVirtualMachineSpecification”第二版。根據(jù)本發(fā)明的優(yōu)選實(shí)施例,通過提供如圖7所示的方便地稱作“分布式運(yùn)行時(shí)間”或DRT71的附加設(shè)施,對(duì)圖6的該公知的現(xiàn)有技術(shù)設(shè)置進(jìn)行修改。在圖7中,應(yīng)用50經(jīng)由分布式運(yùn)行時(shí)間系統(tǒng)71通過箭頭75所指的加載過程被加載到Java虛擬機(jī)72上。分布式運(yùn)行時(shí)間系統(tǒng)可在分布式計(jì)算環(huán)境(DCE)名下從開放軟件基金會(huì)(OpenSoftwareFoundation)獲得。特別是,分布式運(yùn)行時(shí)間71在JAVA應(yīng)用50的箭頭75所指的加載過程期間投入運(yùn)行,以便初始地創(chuàng)建JAVA虛擬機(jī)72。加載期間的操作順序?qū)⒃谙挛闹薪Y(jié)合圖9來描述。圖8示出了利用JAVA虛擬機(jī)的對(duì)圖5設(shè)置的修改形式,所述虛擬機(jī)的每個(gè)如圖7中所示。明顯的是,同一應(yīng)用50再次加載到每個(gè)機(jī)器Ml、M2...Mn上。但是,由箭頭83指示的每個(gè)機(jī)器Ml、M2...Mn間的通信(盡管通過機(jī)器硬件來物理地路由)由每個(gè)機(jī)器內(nèi)的各個(gè)DRT71/1...71/n來控制。因此,實(shí)際上,這可概念化為經(jīng)由網(wǎng)絡(luò)73彼此通信的DRT71/1...71/n,而不是機(jī)器M1、M2...Mn本身。現(xiàn)在轉(zhuǎn)到圖7和圖9,在加載過程75期間,對(duì)被加載來創(chuàng)建JAVA虛擬機(jī)72的程序50進(jìn)行修改。該修改在圖9的90開始,并涉及對(duì)正在加載的應(yīng)用50中的所有存儲(chǔ)器位置(JAVA中稱作字段-但在其他語言中使用相當(dāng)?shù)男g(shù)語)進(jìn)行檢測(cè)的初始步驟91。對(duì)于步驟92和93中的后續(xù)處理需要對(duì)這樣的存儲(chǔ)器位置進(jìn)行標(biāo)識(shí)。在加載過程75期間,DRT71創(chuàng)建如此標(biāo)識(shí)的所有存儲(chǔ)器位置的列表,JAVA字段通過對(duì)象和類來列表。易變字段和同步字段二者均被列出。修改過程的下一階段(圖9中標(biāo)記為92)是在可執(zhí)行的應(yīng)用代碼中搜索,以便定位每個(gè)這樣的處理活動(dòng),該處理活動(dòng)對(duì)與步驟91所產(chǎn)生的列表對(duì)應(yīng)的字段值進(jìn)行操作和改變,且因此寫入到字段,使得對(duì)應(yīng)存儲(chǔ)器位置的值發(fā)生改變。當(dāng)檢測(cè)到這種改變字段值的操作(典型地為JAVA語言中的putstatic或putfield)時(shí),通過步驟93將“updatingpropagationroutine(更新傳播例程)”插入于程序中的該處,以保證將字段值改變通知到所有其他機(jī)器。之后,加載過程如圖9的步驟94所示以正常方式繼續(xù)。圖10示出了加載期間的初始修改的另一形式。這里,起始和列表步驟90和91以及搜索步驟92與圖9中相同。但是,不是如步驟93那樣插入“updatingpropagationroutine(更新傳播例程),,(其中處理線程執(zhí)行該更新),而是在步驟103中插入“alertroutine(告警例程)”。"alertroutine(告警例程)”指示未在處理中使用的或被分配給該DRT的一個(gè)或多個(gè)線程執(zhí)行必要的傳播。該步驟103是一個(gè)導(dǎo)致較低開銷的較快的替選方法。一旦加載過程期間發(fā)生了該初始修改,則發(fā)生圖11和12中所示的多線程處理操作的任一個(gè)。如圖11中可見,包含線程111/1...111/4的機(jī)器上的多線程處理110正在發(fā)生,而第二線程111/2(在該示例中)的處理導(dǎo)致線程111/2在步驟113獲知字段值的改變。在該階段,該線程111/2的正常處理在步驟114被中斷,而同一線程111/2經(jīng)由網(wǎng)絡(luò)53將在步驟113中發(fā)生的被改變的字段的標(biāo)識(shí)和改變的值通知給所有其他機(jī)器M2...Mn。在通12信過程的結(jié)尾,線程111/2然后在步驟115繼續(xù)處理,直到發(fā)生字段值改變的下一實(shí)例。在圖12中所示的另一設(shè)置中,一旦線程121/2在步驟113獲知字段值的改變,其指示DRT處理120(如步驟125和箭頭127所示),分配給DRT處理120的另一(或多個(gè))線程121/1要根據(jù)步驟128經(jīng)由網(wǎng)絡(luò)53將步驟113所檢測(cè)到的改變的字段的標(biāo)識(shí)和改變的值傳播到所有其他機(jī)器M2...Mn。該操作可以快速執(zhí)行,因此,如步驟125所示的,在線程111/2繼續(xù)步驟115中的處理之前,初始線程111/2的處理僅被瞬時(shí)中斷。已被通知了所述改變(如箭頭127所示)的另一線程121/1然后如步驟128所示經(jīng)由網(wǎng)絡(luò)53將該改變傳送給每個(gè)其他機(jī)器M2...Mn。圖12的這第二種設(shè)置更好地利用了各線程111/1...111/3和121/1的處理能力(一般而言,這些線程并不被同等地要求),而且給予了較好的、具有可增加大小的“η”的縮放性(η是大于或等于2的整數(shù),表示連接至網(wǎng)絡(luò)53并同時(shí)運(yùn)行應(yīng)用程序50的機(jī)器總數(shù))。不論使用哪種設(shè)置,改變的字段和標(biāo)識(shí)及步驟113中所檢測(cè)的值均被傳播到網(wǎng)絡(luò)上的所有其他機(jī)器Μ2...Mn。這示于圖13中,其中DRT71/1及圖12中的其線程121/1(圖13中以步驟128來表示)經(jīng)由網(wǎng)絡(luò)53將所列的、在圖12的步驟113通過機(jī)器Ml中的處理所產(chǎn)生的存儲(chǔ)器位置的標(biāo)識(shí)和改變的值傳播到每個(gè)其他機(jī)器Μ2...Mn。通過接收來自網(wǎng)絡(luò)53的標(biāo)識(shí)和值的對(duì)、并將新值寫入本地對(duì)應(yīng)的存儲(chǔ)器位置中,每個(gè)其他機(jī)器Μ2...Mn執(zhí)行圖13中步驟135和136所示的針對(duì)機(jī)器Mn的動(dòng)作。在利用分布式軟件的圖3的現(xiàn)有技術(shù)設(shè)置中,通過互連所述機(jī)器的網(wǎng)絡(luò),允許從一個(gè)機(jī)器軟件到物理地位于另一機(jī)器上的存儲(chǔ)器進(jìn)行訪問。但是,這樣的存儲(chǔ)器訪問可導(dǎo)致機(jī)器中央處理單元的IO6-IO7個(gè)循環(huán)的量級(jí)的處理延遲。這很大程度上解釋了多互連機(jī)器的降低的性能。然而,在上述結(jié)合圖8的本發(fā)明的設(shè)置中,可以理解的是,數(shù)據(jù)的所有讀取均可在本地得到滿足,因?yàn)樗凶侄蔚漠?dāng)前值均存儲(chǔ)在執(zhí)行該處理的機(jī)器上,所述處理產(chǎn)生讀取存儲(chǔ)器的命令。這樣的本地處理可在中央處理單元的IO2-IO3個(gè)循環(huán)內(nèi)得到滿足。因此,實(shí)際上,基本上沒有等待包括讀取的存儲(chǔ)器訪問。然而,大多數(shù)應(yīng)用軟件頻繁地讀取存儲(chǔ)器,而相對(duì)不那么頻繁地寫入存儲(chǔ)器。結(jié)果,與存儲(chǔ)器被讀取的速率相比,寫入或重寫存儲(chǔ)器的速率相對(duì)較慢。由于這種對(duì)存儲(chǔ)器寫入或重寫的慢的需求,可經(jīng)由不昂貴的日常網(wǎng)絡(luò)53以相對(duì)低的速度來持續(xù)更新字段,但該低速度足以滿足應(yīng)用程序?qū)懭氪鎯?chǔ)器的需求。結(jié)果是,圖8的設(shè)置的性能大大優(yōu)于圖3的性能。在與上述有關(guān)的另一實(shí)施例中,改變的字段的標(biāo)識(shí)和值可被分組成批,以便進(jìn)一步降低對(duì)互連各機(jī)器的網(wǎng)絡(luò)53的通信速度的要求。對(duì)本領(lǐng)域普通技術(shù)人員也是明顯的是,在由每個(gè)DRT71在初始記錄字段時(shí)所創(chuàng)建的表中,對(duì)于每個(gè)字段有一個(gè)在整個(gè)網(wǎng)絡(luò)中通用的且網(wǎng)絡(luò)可辨別的名稱或標(biāo)識(shí)。但是,在各個(gè)機(jī)器中,與給定的命名字段對(duì)應(yīng)的存儲(chǔ)器位置將隨時(shí)間變化,因?yàn)槊總€(gè)機(jī)器將根據(jù)其自己的內(nèi)部進(jìn)程逐步地在不同位置存儲(chǔ)改變的字段值。因此,每個(gè)DRT中的表將通常具有不同的存儲(chǔ)器位置,而每個(gè)全局“字段名稱”將具有存儲(chǔ)在不同存儲(chǔ)器位置中的相同“字段值”。對(duì)于本領(lǐng)域普通技術(shù)人員來說也明顯的是,在加載過程中,應(yīng)用程序的上述修改可通過下列多至5種方式來完成(i)加載時(shí)的重新編譯,(ii)在加載前通過預(yù)編譯過程(iii)加載前的編譯(iv)“正好及時(shí)(just-in-time)”的編譯,或(ν)加載后的重新編譯(但是(或例如)在分布式環(huán)境中的相關(guān)或?qū)?yīng)的應(yīng)用代碼執(zhí)行前)。傳統(tǒng)上,術(shù)語“編譯”隱含代碼或語言的改變,例如從源代碼到目標(biāo)代碼或一種語言到另一種的改變。在本說明書中清楚的是,術(shù)語“編譯”(及其語法上的等效)的使用并不如此受限,而亦可包括或包含同一代碼或語言內(nèi)的修改。在第一實(shí)施例中,特定的機(jī)器,如機(jī)器Μ2,將應(yīng)用代碼加載于其自身上,對(duì)其進(jìn)行修改,然后(順序地或同時(shí))以修改的代碼加載每個(gè)其他機(jī)器Ml、Μ3...Mn。在可稱作“主/從”的該設(shè)置中,每個(gè)機(jī)器Ml、M3...Mn加載機(jī)器M2所給予的內(nèi)容。在另一實(shí)施例中,每個(gè)機(jī)器接收應(yīng)用代碼,但在該機(jī)器上對(duì)其進(jìn)行修改并加載修改的代碼。這使得每個(gè)機(jī)器執(zhí)行的修改有些許不同,基于其架構(gòu)和操作系統(tǒng)被優(yōu)化,但仍與其他相似的修改是一致的。在另一設(shè)置中,特定機(jī)器如Ml加載未修改的代碼,而所有其他機(jī)器M2、M3...Mn進(jìn)行修改以刪除原始應(yīng)用代碼并加載修改的版本。在所有實(shí)例中,供給可以有分支(即M2直接供給M1、M3、M4等的每個(gè))或可以是級(jí)聯(lián)或按順序的(即M2供給Ml,然后Ml供給M3,M3再供給M4,依此類推)。在又一實(shí)施例中,機(jī)器Ml至Mn可將所有加載請(qǐng)求發(fā)送給未運(yùn)行應(yīng)用程序的附加機(jī)器(未示出),該附加機(jī)器通過上述方法的任一種來進(jìn)行修改,并將修改的例程返回給機(jī)器Ml至Mn的每個(gè),然后機(jī)器Ml至Mn在本地加載修改的例程。在這種設(shè)置中,機(jī)器Ml至Mn將所有加載請(qǐng)求發(fā)送到該附加機(jī)器,該附加機(jī)器將修改的例程返回給每個(gè)機(jī)器。該附加機(jī)器進(jìn)行的修改可包括本發(fā)明的范圍之內(nèi)所覆蓋的任一修改。計(jì)算領(lǐng)域的普通技術(shù)人員會(huì)知道用于創(chuàng)建計(jì)算機(jī)代碼中的修改的至少4種技術(shù)。第一種是以原始(源)語言進(jìn)行的修改。第二種是將原始代碼(如JAVA)轉(zhuǎn)換成中間表示(或中間語言)。一旦發(fā)生轉(zhuǎn)換,就進(jìn)行修改,然后再反向轉(zhuǎn)換。這給出修改的JAVA代碼的期望結(jié)果。第三種可能性是(直接或經(jīng)由上述中間語言)轉(zhuǎn)換成機(jī)器代碼。然后在加載和執(zhí)行前對(duì)機(jī)器代碼進(jìn)行修改。第四種可能性是將原始代碼轉(zhuǎn)換成中間表示,然后對(duì)中間表示進(jìn)行修改,隨后轉(zhuǎn)換成機(jī)器代碼。本發(fā)明涵蓋所有4種修改例程,也涵蓋2種、3種或甚至4種所述例程的組合。現(xiàn)在轉(zhuǎn)到圖4,示出了作為JAVA虛擬機(jī)運(yùn)行的單個(gè)現(xiàn)有技術(shù)計(jì)算機(jī)的示意圖。以這種方式,(由各制造商的任一個(gè)來生產(chǎn)并具有以各種不同語言的任一種來操作的操作系統(tǒng)的)機(jī)器能以應(yīng)用程序50的特定語言來運(yùn)行,在該實(shí)例中為JAVA語言。也就是說,JAVA虛擬機(jī)72能夠運(yùn)行JAVA語言的代碼50,并利用JAVA架構(gòu),而不管機(jī)器制造商和機(jī)器的內(nèi)部細(xì)節(jié)。14在JAVA語言中,初始化例程<clinit>僅在加載給定類文件50A時(shí)發(fā)生一次。但是初始化例程<init>頻繁發(fā)生,例如,每次創(chuàng)建新對(duì)象50X、50Y和50Ζ時(shí)都發(fā)生。此外,類是在對(duì)象前加載的,這樣在圖14所示的具有單個(gè)類50Α和三個(gè)對(duì)象50Χ-50Ζ的應(yīng)用程序中,首先加載第一類50Α,然后加載第一對(duì)象50Χ,然后加載第二對(duì)象50Υ,最后加載第三對(duì)象50Ζ。這里,如圖14中所示,僅有單個(gè)計(jì)算機(jī)或機(jī)器72,于是要在加載過程期間工作的初始化例程的運(yùn)行中沒有出現(xiàn)沖突或不一致。但是,在圖8(還有圖31-33)所示的設(shè)置中,提供了多個(gè)單獨(dú)的計(jì)算機(jī)或機(jī)器Ml、M2...Mn,其每個(gè)經(jīng)由通信網(wǎng)絡(luò)53來互連,且其每個(gè)被提供有修改器51并加載有普通應(yīng)用程序50。實(shí)質(zhì)上,修改器51用來復(fù)制各機(jī)器M1、M2...Mn的每個(gè)上的相同存儲(chǔ)器結(jié)構(gòu)和內(nèi)容。因此結(jié)果是,在這種計(jì)算環(huán)境中,有必要保證各機(jī)器Ml、M2...Mn的每個(gè)以一致的方式來初始化。圖5的修改器51的修改功能由圖8中的DRT71來提供。為了保證一致的初始化,應(yīng)用程序50被仔細(xì)檢查,以便檢測(cè)定義初始化例程的程序步驟。該仔細(xì)檢查可在加載前、或加載過程75期間、或甚至在加載過程75之后(但在相關(guān)對(duì)應(yīng)的應(yīng)用代碼執(zhí)行之前)發(fā)生。編譯過程可這樣理解即術(shù)語編譯通常涉及代碼或語言上的改變,如從源代碼到目標(biāo)代碼或從一種語言到另一種的改變。但是,在本實(shí)例中,術(shù)語“編譯”(及其語法上的等效)并不受限于此,而是也可包含同一代碼或語言中的修改。結(jié)果,在上述仔細(xì)檢查中,初始地查找<clinit>例程,當(dāng)找到時(shí),插入修改代碼(一般是幾個(gè)指令),以便引起被修改的<clinit>例程的發(fā)生。該被修改的例程要將類50A加載到機(jī)器之一上,例如JVM#1上,并告知其他機(jī)器M2...Mn存在這樣的類50A及其當(dāng)前狀態(tài)。存在可執(zhí)行這種修改和加載的幾種不同的模式。因此,在一個(gè)模式中,加載機(jī)器(在本例中是JVM#1)上的DRT71詢問所有其他機(jī)器的DRT71/2...71/n是否已經(jīng)初始化了第一類50A。如果對(duì)該問題的回答為肯定,則關(guān)斷或禁止正常的初始化過程。如果回答為否,則進(jìn)行正常的初始化過程,而且在該過程期間產(chǎn)生的結(jié)果的變化將傳送給所有其他機(jī)器,如圖8中的箭頭83所示。每次要加載對(duì)象如50X、50Y或50Z時(shí)會(huì)發(fā)生相似的過程。如果在調(diào)查后DRT71/1沒有察覺到正在考慮的特定對(duì)象如對(duì)象50Υ已經(jīng)加載到其他機(jī)器Μ2...Mn上,那么,DRT71/1運(yùn)行對(duì)象初始化例程,并將等效對(duì)象(可方便地稱作對(duì)等對(duì)象)連同初始值的拷貝一起加載到其他機(jī)器Μ2...Mn的每個(gè)上。但是,如果DRT71/1確定正在考慮的對(duì)象50Υ已經(jīng)存在于其他機(jī)器上,則禁止正常的初始化功能,并利用當(dāng)前值的拷貝來創(chuàng)建本地拷貝。同樣,存在用于產(chǎn)生期望結(jié)果的各種方式。如圖15中所示,提供了對(duì)圖8的通用設(shè)置的修改,其中機(jī)器Ml、Μ2...Mn如前所述,并在所有機(jī)器Ml、M2...Mn上同時(shí)運(yùn)行同一應(yīng)用程序(或多個(gè)程序)50。但是,以提供服務(wù)器機(jī)器X的方式對(duì)前述設(shè)置進(jìn)行了修改,所述服務(wù)器機(jī)器X能夠方便地提供管家(housekeeping)功能,特別是結(jié)構(gòu)、資產(chǎn)和資源的初始化、清理和/或同步。因?yàn)槠溆?jì)算負(fù)載低,所以這種服務(wù)器機(jī)器X可以是低價(jià)值的日常計(jì)算機(jī),如PC。如圖15的虛線所示,為了備份的目的,可提供兩個(gè)服務(wù)器機(jī)器X和X+1,以便提高系統(tǒng)的總體可靠性。當(dāng)提供兩個(gè)這種服務(wù)器機(jī)器X和X+1時(shí),它們優(yōu)選地作為一個(gè)簇中的雙重機(jī)器來工作。如圖15的虛線所示,附加機(jī)器X+1是可選的。提供服務(wù)器機(jī)器X不是必須的,因?yàn)槠溆?jì)算可以分布在機(jī)器Ml、M2...Mn上??商?5換地,一個(gè)機(jī)器操作的數(shù)據(jù)庫(kù)(在主/從型操作中)可用于所述的管家功能。圖16示出了初始化所要遵循的優(yōu)選通用過程。在加載步驟161已經(jīng)開始后,按照順序考慮待執(zhí)行的指令,并檢測(cè)所有初始化例程,如步驟162所示。在JAVA語言中,這些為<init>和<clinit>例程(或JAVA術(shù)語中的方法(method))。其他語言使用不同的術(shù)語。當(dāng)步驟162中檢測(cè)到初始化例程時(shí),在步驟163中,典型地通過將進(jìn)一步的指令插入到例程中來對(duì)其進(jìn)行修改。可替換地,可在例程前插入修改指令。一旦完成了修改步驟163,則如步驟164所示,繼續(xù)加載過程。圖17示出了修改的特定形式。在開始步驟171中的例程之后,在步驟172中,給待初始化的結(jié)構(gòu)、資產(chǎn)或資源(在JAVA中稱作類或?qū)ο?分配名稱或標(biāo)簽,這些名稱或標(biāo)簽可以被所有機(jī)器在全局中使用。這是通過圖15的服務(wù)器機(jī)器X所維護(hù)的表來最方便地完成的。該表還包括待初始化的類或?qū)ο蟮臓顟B(tài)。如圖17所示,如果步驟173和174確定全局名稱還未在其他地方(即執(zhí)行加載的機(jī)器以外的機(jī)器)初始化,則這意味著由于這是要?jiǎng)?chuàng)建的第一個(gè)這種對(duì)象或類,因此可通過執(zhí)行步驟176來以正常方式初始化所述對(duì)象或類。但是,如果步驟173和174確定所述全局名稱已經(jīng)在其他地方初始化了,則這意味著另一機(jī)器已經(jīng)初始化了該類或?qū)ο?。因此,通過執(zhí)行步驟175,常規(guī)初始化例程被完全中止。圖18示出了加載機(jī)器(Ml、M2...Mn之一)向圖15的服務(wù)器機(jī)器X所作的問詢。如步驟181所示,加載機(jī)器的操作被暫時(shí)中斷,直到收到來自機(jī)器X的回復(fù),如步驟182所7J\ο圖19示出了圖15的服務(wù)器機(jī)器X響應(yīng)于圖18步驟181的這種問詢而進(jìn)行的活動(dòng)。在步驟192和193中確定初始化狀態(tài),如果已經(jīng)初始化,則通過執(zhí)行步驟194來將具有該意思的響應(yīng)發(fā)送到問詢的機(jī)器。同樣,如果初始化狀態(tài)是未初始化,則通過執(zhí)行步驟195和196來發(fā)送對(duì)應(yīng)的回復(fù)。然后,通過步驟182來創(chuàng)建的等待的問詢的機(jī)器能夠相應(yīng)地作出響應(yīng)。參考附件,其中附件Al-AlO示出與字段相關(guān)的實(shí)際代碼,附件Bl是來自未修改的<clinit>指令的典型代碼片段,附件B2是關(guān)于修改的<clinit>指令的等效,附件B3是來自未修改的<init>指令的典型代碼片段,附件B4是關(guān)于修改的<init>指令的等效,此外,附件B5是附件B2的代碼的替代,以及附件B6是附件B4的代碼的替代。另外,附件B7是InitClient的源代碼,其向“初始化服務(wù)器(initializationserver)”查詢有關(guān)類或?qū)ο蟮某跏蓟癄顟B(tài)。附件B8是InitServer的源代碼,其接收InitClient的初始化狀態(tài)查詢,并作出響應(yīng)將對(duì)應(yīng)的狀態(tài)返回。相似地,附件B9是附件B1-B6的實(shí)例之前/之后所使用的示例應(yīng)用的源代碼。現(xiàn)在轉(zhuǎn)向圖20,示出了修改與類相關(guān)的<clinit>例程以便從附件Bl的代碼片段轉(zhuǎn)換成附件B2的代碼片段的所遵循的過程。在步驟201開始將應(yīng)用程序50初始加載到JAVA虛擬機(jī)72上,通過執(zhí)行步驟202,仔細(xì)檢查每行代碼,以便檢測(cè)那些代表<clinit>例程的指令。一旦檢測(cè)到,通過執(zhí)行步驟203,如附件B2中所示對(duì)<clinit>例程進(jìn)行修改。如步驟204所示,修改完成后,繼續(xù)加載過程。附件Bl和B2分別是摘錄<clinit>指令之前和之后。添加到該方法(method)中的修改的代碼以粗體突出顯示。在附件Bl的原始代碼樣本中,<clinit>方法創(chuàng)建其自己的新對(duì)象,并將其寫入稱作“thisTest”的存儲(chǔ)器位置(字段)。因此,在沒有分布式環(huán)境中的類加載管理的情況下,每個(gè)機(jī)器將以不同對(duì)象來重新初始化同樣的共享存儲(chǔ)器位置(字段)。顯然這不是正加載的應(yīng)用程序的程序員所期望發(fā)生的。因此,利用DRT,通過改變<clinit>方法,在應(yīng)用代碼加載到機(jī)器中時(shí)對(duì)其進(jìn)行修改。所作的改變(以粗體突出顯示)是<clinit>方法執(zhí)行的初始指令。通過調(diào)用isAlreadyLoadedO方法,所添加的這些指令檢查該類是否已經(jīng)加載,isAlreadyLoaded()方法返回與該類的加載狀態(tài)對(duì)應(yīng)的真或假。DRT的該isAlreadyLoadedO方法可以任選地采用代表該類的唯一標(biāo)識(shí)符的自變量(見附件B5和B6),例如在確定該類的加載狀態(tài)時(shí)將使用的類的名稱、或代表該類的類對(duì)象、或在所有機(jī)器上表示該類的唯一號(hào)碼。這樣,通過使用每個(gè)類的唯一標(biāo)識(shí)符來咨詢isAlreadyLoaded表中的正確記錄,DRT可同時(shí)支持多個(gè)類的加載,而不會(huì)混淆多個(gè)類中哪些已加載,哪些未加載。DRT可以多種方式來確定類的加載狀態(tài)。優(yōu)選地,如果該類已加載,DRT可依次問詢每個(gè)機(jī)器是否該類已被加載,而如果有任何機(jī)器回復(fù)真,則返回真,否則返回假??商鎿Q地,本地機(jī)器上的DRT可咨詢共享的記錄表(也許在單獨(dú)的機(jī)器上(如機(jī)器X),或咨詢本地機(jī)器上的一致的共享記錄表,或數(shù)據(jù)庫(kù))來確定該類是否已經(jīng)加載。如果DRT返回假,則這意味著該類以前還未加載到分布式環(huán)境中的任何機(jī)器上,因此,該執(zhí)行將視為第一次和原始的。結(jié)果,DRT必須將共享記錄表中該類的"isAlreadyLoaded"記錄更新為真,這樣,現(xiàn)在在所有其他機(jī)器上,包括當(dāng)前機(jī)器上,isAlreadyLoaded的所有隨后的引用均將返回真。因此,如果DRT.isAlreadyLoadedO返回假,則修改的<clinit>方法繼續(xù)執(zhí)行原始代碼塊,其現(xiàn)在跟在被插入的三個(gè)指令之后。另一方面,如果DRT返回真,則這意味著該類已經(jīng)加載于分布式環(huán)境中,如被加載的類的共享記錄表中所記載的那樣。在這種情況下,由于其將覆寫已經(jīng)初始化的存儲(chǔ)器位置等,因此不執(zhí)行原始代碼塊。因而,當(dāng)DRT返回真時(shí),所插入的三個(gè)指令防止執(zhí)行原始代碼,并直接返回應(yīng)用程序。圖21示出了與對(duì)象有關(guān)的<init>例程的等效過程,其中步驟212和213相當(dāng)于圖20中的步驟202和203。這導(dǎo)致附件B3的代碼被轉(zhuǎn)換成附件B4的代碼。針對(duì)<clinit>的相似修改也用于<init>。如步驟212所示檢測(cè)應(yīng)用程序的<init>塊(或多個(gè)<init>塊,因?yàn)榭梢源嬖诙鄠€(gè),這與<clinit>不同),并如步驟213所示對(duì)其進(jìn)行修改,以便在分布式環(huán)境上一致地運(yùn)轉(zhuǎn)。在附件B3的示例中,應(yīng)用程序的<init>指令利用加載時(shí)間的時(shí)間戳來初始化存儲(chǔ)器位置(字段)。例如,應(yīng)用可用此來記錄該對(duì)象是何時(shí)創(chuàng)建的。顯然,在對(duì)等對(duì)象可在不同時(shí)間加載的分布式環(huán)境中,需要特殊的處理,以保證首先加載的對(duì)等對(duì)象的時(shí)間戳不17被后來的對(duì)等對(duì)象所覆寫。修改發(fā)生后的被分解的指令序列示于附件B4中,而且所修改/插入的指令以粗體突出顯示。對(duì)于<init>修改,與<clinit>修改不同的是,通常要求將修改指令置于“invokespecial”指令之后,而不是在剛開始的位置。這樣作的原因是JAVA虛擬機(jī)規(guī)范所要求的。其他語言經(jīng)常具有相似的細(xì)微的設(shè)計(jì)差別。測(cè)試的基本概念是初始化是否已經(jīng)執(zhí)行,如果沒有,則進(jìn)行,如果已經(jīng)執(zhí)行,則不再執(zhí)行進(jìn)一步的初始化;存在幾種可以執(zhí)行這個(gè)概念的不同方式。在第一實(shí)施例中,特定機(jī)器如機(jī)器M2將類或?qū)ο蠹虞d于其自身上,然后(按順序或同時(shí)地)加載其他機(jī)器Ml、M3...Mn的每一個(gè)。在該可稱作“主/從”的設(shè)置中,機(jī)器Ml、M3...Mn的每一個(gè)加載機(jī)器M2所給予的內(nèi)容。在該“主/從”設(shè)置的一種變型中,機(jī)器M2將未修改形式的<clinit>例程加載到機(jī)器M2上,然后通過整個(gè)刪除初始化例程來修改該類,并將修改后的類加載到其他機(jī)器上。這樣,在該實(shí)例中,修改不是繞過初始化例程,而是將其從除一個(gè)機(jī)器以外的所有機(jī)器上刪除。在又一實(shí)施例中,每個(gè)機(jī)器接收初始化例程,但對(duì)其進(jìn)行修改,并將修改后的例程加載于該機(jī)器上。這使得每個(gè)機(jī)器執(zhí)行的修改能夠有些許不同,基于其架構(gòu)和操作系統(tǒng)來優(yōu)化,但是仍然與所有其他相似的修改一致。在又一設(shè)置中,特定機(jī)器如Ml加載類,而所有其他機(jī)器M2、M3...Mn進(jìn)行修改以刪除初始化例程并加載修改后的版本。在所有實(shí)例中,供給可以有分支(即M2直接供給M1、M3、M4等的每個(gè))或可以是級(jí)聯(lián)或按順序的(即M2供給Ml,然后Ml供給M3,M3再供給M4,依此類推)。在又一設(shè)置中,初始機(jī)器如M2可執(zhí)行初始加載,然后產(chǎn)生列出機(jī)器M2所加載的所有類的表。該表然后(以分支或級(jí)聯(lián)的方式)被發(fā)送給所有其他機(jī)器。然后,如果除了M2以外的一個(gè)機(jī)器需要訪問所述表中列出的類,則其發(fā)送請(qǐng)求給M2,以提供必要的信息。因此,提供給機(jī)器Mn的信息通常不同于加載到機(jī)器M2中的初始狀態(tài)。在上述情況下,有必要使表中每個(gè)條目附帶一個(gè)計(jì)數(shù)器,該計(jì)數(shù)器在每次加載類時(shí)增加。因而,當(dāng)需要數(shù)據(jù)時(shí),響應(yīng)于該需求來傳送類內(nèi)容和對(duì)應(yīng)計(jì)數(shù)器的計(jì)數(shù)二者。這種“按要求的(ondemand)”模式增加了每個(gè)計(jì)算機(jī)的開銷,但減少了互連計(jì)算機(jī)的通信網(wǎng)絡(luò)上的流量。在又一設(shè)置中,機(jī)器Ml...Mn可將所有加載請(qǐng)求發(fā)送給(圖15的)附加機(jī)器X,該附加機(jī)器X通過上述方法中的任一種來執(zhí)行修改,并將修改后的類返回給機(jī)器Ml...Mn的每個(gè),機(jī)器Ml...Mn的每個(gè)然后在本地加載該類。在這種設(shè)置中,機(jī)器Ml...Mn不維護(hù)任何類的記錄表,相反,它們將所有加載請(qǐng)求轉(zhuǎn)發(fā)到機(jī)器X,機(jī)器X維護(hù)加載類的表,并根據(jù)給定類是否是第一次加載到機(jī)器Ml...Mn上,將修改后的類返回給每個(gè)機(jī)器。機(jī)器X進(jìn)行的修改可包括本發(fā)明的范圍覆蓋的任何修改。再參考圖14,在JAVA語言中,初始化例程<clinit>僅在加載給定類文件50A時(shí)發(fā)生一次。但是初始化例程<init>經(jīng)常發(fā)生,例如,每次創(chuàng)建新對(duì)象50X、50Y和50Ζ時(shí)都發(fā)生。此外,類是在對(duì)象之前加載的,這樣,在圖14所示的具有單個(gè)類50Α和三個(gè)對(duì)象50Χ-50Ζ的應(yīng)用程序中,首先加載第一類50Α,然后加載第一對(duì)象50Χ,然后加載第二對(duì)象50Υ,最后18加載第三對(duì)象50Z。這里,如圖14中所示,僅有單個(gè)計(jì)算機(jī)或機(jī)器72,而因?yàn)閳D14的單個(gè)機(jī)器能夠容易地跟蹤特定對(duì)象50X-50Z將來是否傾向于被需要用于程序50,因此,旨在加載過程期間工作的初始化例程的運(yùn)行中沒有出現(xiàn)沖突或不一致。這是通過維護(hù)“handlecount”等來完成的。該計(jì)數(shù)跟蹤可執(zhí)行代碼中對(duì)特定對(duì)象進(jìn)行引用之處的數(shù)量。當(dāng)特定對(duì)象的handlecount達(dá)到0時(shí),在可執(zhí)行代碼中沒有對(duì)該對(duì)象進(jìn)行引用之處。這于是該對(duì)象被稱作“可終結(jié)化”。一旦達(dá)到該狀態(tài),由于不再需要,因此可安全地刪除(或清理或終結(jié)化)該對(duì)象。相同的過程將必要的修正(mutatismutandis)施加于類。特別是,計(jì)算機(jī)程序員在使用JAVA語言和架構(gòu)來編寫程序時(shí),不需要為該清理、刪除和終結(jié)化編寫任何具體代碼。相反,單個(gè)JAVA虛擬機(jī)72可跟蹤類和對(duì)象的handlecount,并以不引人注意的方式在需要時(shí)進(jìn)行清理(或進(jìn)行終結(jié)化)。但是,在圖8(還有圖31-33)中所示的設(shè)置中,提供了多個(gè)單獨(dú)的計(jì)算機(jī)或機(jī)器M1、M2...Mn,其每個(gè)經(jīng)由通信網(wǎng)絡(luò)53來互連,且其每個(gè)被提供有修改器51(如圖5中所示,并通過圖8中的DRT71實(shí)現(xiàn))并加載有公共應(yīng)用程序50。實(shí)質(zhì)上,修改器51或DRT71修改應(yīng)用代碼50,以在多個(gè)單獨(dú)的機(jī)器M1、M2...Mn上執(zhí)行清理例程。因此隨之而來的是,使得在這種計(jì)算環(huán)境中,有必要保證各機(jī)器的每個(gè)以(關(guān)于彼此)一致的方式來終結(jié)化。特別地,盡管一個(gè)特定機(jī)器(如M3)可不再調(diào)用一對(duì)象或類,但另一機(jī)器(如M5)在將來可仍然需要引用該對(duì)象和類。因此,如果要從機(jī)器M3上刪除該對(duì)象或類,那么如果M5要寫入該對(duì)象或修改其值,則由于M3在其本地存儲(chǔ)器中沒有包括該相關(guān)的對(duì)象,因此該值的改變就不會(huì)傳播到所有機(jī)器Ml、M2...Mn。另外,如果機(jī)器M3要執(zhí)行對(duì)給定對(duì)象或類的清理例程,清理例程將不僅針對(duì)該機(jī)器上的該對(duì)象進(jìn)行清理,而是針對(duì)所有其他機(jī)器上的對(duì)等對(duì)象。因而,使得機(jī)器M5上的該對(duì)象無效。這樣,就不會(huì)實(shí)現(xiàn)同一應(yīng)用程序的同時(shí)運(yùn)行所要求的、機(jī)器Ml、M2...Mn的每個(gè)的基本相同的存儲(chǔ)器內(nèi)容的目標(biāo)。為了保證一致的終結(jié)化或清理,應(yīng)用程序50被仔細(xì)檢查,以便檢測(cè)定義清理例程的程序步驟。該仔細(xì)檢查可在加載前、或加載過程期間、或甚至在加載過程之后(但在應(yīng)用代碼50的相關(guān)對(duì)應(yīng)部分的執(zhí)行之前)發(fā)生。編譯過程可這樣理解即術(shù)語編譯通常涉及代碼或語言上的改變,如從源代碼到目標(biāo)代碼或從一種語言到另一種。但是,在本實(shí)例中,術(shù)語“編譯”(及其語法上的等效)并不受限于此,而可包括包含同一代碼或語言中的修改。結(jié)果,在上述仔細(xì)檢查中,初始地查找清理例程,當(dāng)找到時(shí),插入修改代碼,以便引起修改后的清理例程的發(fā)生。該修改后的例程要在任何特定機(jī)器上中止該清理例程,除非所有其他機(jī)器均將該待刪除的對(duì)象或類標(biāo)記為刪除。存在可執(zhí)行這種修改和加載的幾種不同的模式。在這點(diǎn)上,參考附件C,其中闡述了各種清理或終結(jié)化的示例。因此,在一種模式中,加載機(jī)器(在本例中是JVM#1)上的DRT71/1詢問所有其他機(jī)器的DRT71/2...71/n例如是否任何其他機(jī)器M2.··Mn利用了(即沒有標(biāo)記為刪除)第一類50A。如果對(duì)該問題的回答為肯定,則針對(duì)機(jī)器JVM#1上的第一對(duì)象50X來關(guān)斷或禁止正常的清理過程。如果回答為否(即第一對(duì)象50X在所有其他機(jī)器M2...Mn上標(biāo)記為刪除),則進(jìn)行正常的清理過程,而且不僅從機(jī)器JVM#1上而且從所有其他機(jī)器M2...Mn上刪除第一對(duì)象50X。優(yōu)選地,該清理任務(wù)分配給將對(duì)象或類標(biāo)記為刪除的最后的機(jī)器Ml。圖22示出了關(guān)于終結(jié)化所遵循的優(yōu)選通用過程。在開始加載161A之后,待執(zhí)行的指令按順序來考慮,并且如在步驟162A中所示地檢測(cè)所有清理例程。在JAVA語言中,這些是“finalizeO”例程(或JAVA術(shù)語中的方法)。其他語言使用不同的術(shù)語。當(dāng)檢測(cè)到初清理例程時(shí),在步驟163A中,典型地通過將進(jìn)一步的指令插入到例程中來對(duì)其進(jìn)行修改??商鎿Q地,可在例程之前插入修改指令。一旦完成了修改,則如步驟164A所示,繼續(xù)加載過程。圖23示出了修改的一種特殊形式。首先,如步驟172A中所示,可能是被清理的候選的結(jié)構(gòu)、資產(chǎn)或資源(在JAVA中稱作類或?qū)ο?50A、50X...50Y,已經(jīng)被分配了名稱或標(biāo)簽,所述名稱或標(biāo)簽可由所有機(jī)器M1、M2...Mn在全局使用。這優(yōu)選地發(fā)生于對(duì)類或?qū)ο筮M(jìn)行原始初始化時(shí)。這是通過服務(wù)器機(jī)器X所維護(hù)的表來最方便地完成的。該表還包括類或?qū)ο蟮摹癱leanupstatus(清理狀態(tài))”。在該優(yōu)選實(shí)施例中,該表還包括存儲(chǔ)已經(jīng)將該資產(chǎn)標(biāo)記為刪除的機(jī)器數(shù)量的計(jì)數(shù)的計(jì)數(shù)器。因此,小于(n-1)的總計(jì)數(shù)值表示作為網(wǎng)絡(luò)整體針對(duì)該資產(chǎn)的“donotcleanup(不清理)”狀態(tài)。如圖23所示,如果全局名稱未在所有其他機(jī)器(即除了提請(qǐng)執(zhí)行清理例程的機(jī)器以外)上標(biāo)記為刪除,則如步驟174A所示,這意味著由于仍然需要該對(duì)象或類,應(yīng)該中止所提請(qǐng)的對(duì)該對(duì)象或類的清理例程。如果全局名稱在所有其他機(jī)器上標(biāo)記為刪除,則這意味著其他機(jī)器不再需要該類或?qū)ο?。結(jié)果可以,并且應(yīng)該執(zhí)行步驟176A所示的正常清理例程。圖24示出提請(qǐng)執(zhí)行清理例程的機(jī)器(Ml、M2...Mn之一)向服務(wù)器機(jī)器X所作的問詢。如步驟181A和182A所示,該提請(qǐng)的機(jī)器的操作被臨時(shí)中斷,直到收到來自機(jī)器X的回復(fù),如步驟182A所示。圖25示出了機(jī)器X響應(yīng)于這種問詢而進(jìn)行的活動(dòng)。如步驟192A所示確定清理狀態(tài),如果否-指定的資源在(n-1)個(gè)機(jī)器上未被標(biāo)記為刪除(即在其他地方使用),則帶有那個(gè)意思的響應(yīng)被發(fā)送到問詢的機(jī)器194A,而“markedfordeletion(標(biāo)記為刪除)”計(jì)數(shù)器增一(1),如步驟197A所示。相似地,如果回答為肯定-如步驟195A所示的那樣發(fā)送對(duì)應(yīng)的回復(fù)。等待問詢的機(jī)器182A然后能夠相應(yīng)地作出響應(yīng)。如圖25中虛線所示,優(yōu)選地,除了步驟195A中所示的肯定響應(yīng)之外,還對(duì)共享的表進(jìn)行更新,這樣,全局命名的資產(chǎn)的狀態(tài)變成“清理”,如步驟196A所示。再參考圖14,當(dāng)通過程序員使用同步例程來規(guī)定時(shí),圖14的單個(gè)機(jī)器能夠容易地執(zhí)行特定對(duì)象50X-50Z的同步。由于每個(gè)對(duì)象僅在本地存在,圖14的單個(gè)JAVA虛擬機(jī)能夠保證對(duì)象如程序員規(guī)定的那樣被正確同步,因此在任何單個(gè)時(shí)間點(diǎn)僅為可執(zhí)行代碼的一部分來使用。如果另一部分可執(zhí)行代碼希望使用相同的對(duì)象,則可能的競(jìng)爭(zhēng)由JAVA虛擬機(jī)這樣來解決,也即應(yīng)用程序的其他執(zhí)行部分只好等待直到第一部分完成。同一過程對(duì)類50A施加必要的修正。特別是,當(dāng)使用JAVA語言和架構(gòu)來編寫程序時(shí),計(jì)算機(jī)程序員僅需使用同步例程,以便提供該競(jìng)爭(zhēng)避免。這樣,單個(gè)JAVA虛擬機(jī)可跟蹤多個(gè)類和對(duì)象的使用,并以不引人注意的方式在需要時(shí)避免任何對(duì)應(yīng)的問題。僅一個(gè)對(duì)象或類被獨(dú)占地使用的過程稱作“同步”。在JAVA語言中,指令“monitorenter”和“monitorexit”表示同步例程的開始和結(jié)束,其分別導(dǎo)致對(duì)“l(fā)ock”的獲取和釋放,所述“l(fā)ock”防止資產(chǎn)為競(jìng)爭(zhēng)的主題。但是,在圖8(還有圖31-33)中所示的設(shè)置中,提供了多個(gè)單獨(dú)的計(jì)算機(jī)或機(jī)器M1、M2...Mn,其每個(gè)經(jīng)由通信網(wǎng)絡(luò)53來互連,且其每個(gè)被提供有修改器51(如圖5中所示,并通過圖8中的DRT71實(shí)現(xiàn))并加載有公共應(yīng)用程序50。實(shí)質(zhì)上,修改器51或DRT71保證當(dāng)在一個(gè)機(jī)器上運(yùn)行的應(yīng)用程序50的部分(例如利用同步)獨(dú)占地使用特定本地資產(chǎn)(如對(duì)象50X-50Z或類50A)時(shí),其他機(jī)器M2...Mn不在其本地存儲(chǔ)器中使用對(duì)應(yīng)的資產(chǎn)。特別地,盡管一個(gè)特定機(jī)器(如M3)獨(dú)占地使用一對(duì)象或類,但另一機(jī)器(如M5)也有可能被其執(zhí)行的代碼指示來在該時(shí)獨(dú)占使用該對(duì)象和類。因此,如果該對(duì)象或類要被二者獨(dú)占使用,那么該對(duì)象和應(yīng)用作為一個(gè)整體的行為沒有定義-也就是說,在對(duì)象的正確獨(dú)占使用沒有被程序員明確規(guī)定的情況下,可能會(huì)導(dǎo)致機(jī)器M5和機(jī)器M3之間的永久不一致。這樣,就不會(huì)實(shí)現(xiàn)同一應(yīng)用程序的同時(shí)運(yùn)行所要求的、每個(gè)機(jī)器Ml、M2...Mn的基本相同的存儲(chǔ)器內(nèi)容的目標(biāo)。為了保證一致的同步,應(yīng)用程序50被仔細(xì)檢查,以便檢測(cè)定義同步例程的程序步驟。該仔細(xì)檢查可在加載前、或加載過程期間、或甚至在加載過程之后(但在相關(guān)對(duì)應(yīng)的應(yīng)用代碼執(zhí)行之前)發(fā)生。編譯過程可這樣理解即術(shù)語編譯通常涉及代碼或語言上的改變,如從源到目標(biāo)代碼或從一種語言到另一種。但是,在本實(shí)例中,術(shù)語“編譯”(及其語法上的等效)并不受限于此,而可包括包含同一代碼或語言中的修改。參考附件D,其中附件Dl是來自未修改的同步例程的典型代碼片段,以及附件D2是關(guān)于所修改的同步例程的等效,附件Dl和D2分別在同步例程的摘錄之前和之后。添加到該方法的修改代碼以粗體突出顯示。在附件Dl的原始代碼樣本中,代碼在同步聲明內(nèi)增加共享存儲(chǔ)器位置(計(jì)數(shù)器)。同步聲明的目的是為了保證多線程應(yīng)用中的增量操作的線程安全性。因此,在分布式環(huán)境中沒有同步管理的情況下,每個(gè)機(jī)器將在隔離中執(zhí)行同步,由此有可能同時(shí)增加共享的計(jì)數(shù)器,導(dǎo)致潛在的競(jìng)態(tài)條件和不一致的存儲(chǔ)器。顯然這不是應(yīng)用程序的程序員所期望發(fā)生的。因此,利用DRT,通過改變同步例程,在應(yīng)用代碼加載到機(jī)器中時(shí)被進(jìn)行修改。所作的修改(以粗體突出顯示)是同步例程所執(zhí)行的初始指令和結(jié)束指令。這些添加的指令用于在分布式環(huán)境中的所有其他機(jī)器上附加地執(zhí)行同步,由此保持多個(gè)機(jī)器上應(yīng)用程序的同步行為。DRT的acquireLock()方法利用表示該對(duì)象的唯一標(biāo)識(shí)符的自變量(見附件D2),例如對(duì)象名稱、正在考慮的對(duì)象的引用或在所有節(jié)點(diǎn)上表示該對(duì)象的唯一號(hào)碼,以在獲得規(guī)定對(duì)象的全局鎖定中使用。這樣,通過使用每個(gè)對(duì)象的唯一標(biāo)識(shí)符來咨詢共享同步表中的正確記錄,DRT可同時(shí)支持多個(gè)對(duì)象的同步,而不會(huì)混淆多個(gè)對(duì)象的哪個(gè)已經(jīng)同步哪個(gè)還沒有同步。DRT可以多種方式來確定對(duì)象的同步狀態(tài)。優(yōu)選地,其可依次問詢每個(gè)機(jī)器其對(duì)該對(duì)象的本地拷貝當(dāng)前是否同步,而如果有任何機(jī)器回復(fù)真,則等待直到該對(duì)象不同步,否則在本地對(duì)該對(duì)象進(jìn)行同步??商鎿Q地,本地機(jī)器上的DRT可咨詢共享的記錄表(也許在單獨(dú)的機(jī)器上(如機(jī)器X),或本地機(jī)器上一致的共享記錄表,或數(shù)據(jù)庫(kù))來確定該對(duì)象是否已經(jīng)由任何其他機(jī)器標(biāo)記為同步,如果是這樣,則等待直到該對(duì)象的狀態(tài)變?yōu)椤安煌健保缓笸ㄟ^將該對(duì)象標(biāo)記為同步來獲得鎖定,否則通過由該機(jī)器將該對(duì)象標(biāo)記為同步來獲得鎖21定。如果DRT確定當(dāng)前沒有其他機(jī)器具有對(duì)該對(duì)象的鎖定(即沒有其他機(jī)器已經(jīng)將該對(duì)象同步),則例如通過修改同步狀態(tài)共享表中的對(duì)應(yīng)條目,或可替換地,通過順序獲得除當(dāng)前機(jī)器以外的所有其他機(jī)器上的鎖定,在所有其他機(jī)器上獲得對(duì)該對(duì)象的鎖定。只有當(dāng)該機(jī)器成功確認(rèn)當(dāng)前沒有其他機(jī)器已對(duì)該對(duì)象同步、并且該機(jī)器已在本地對(duì)應(yīng)同步時(shí),原始同步代碼塊才開始執(zhí)行。另一方面,如果DRT確定另一機(jī)器已經(jīng)對(duì)該對(duì)象進(jìn)行了同步,那么該機(jī)器將推遲執(zhí)行原始同步代碼塊,直到DRT可確認(rèn)沒有其他機(jī)器當(dāng)前正在執(zhí)行針對(duì)該對(duì)象的同步聲明而且該機(jī)器已經(jīng)在本地對(duì)該對(duì)象進(jìn)行了對(duì)應(yīng)的同步。在這種情況下,將不執(zhí)行原始代碼塊,直到該機(jī)器可確保沒有其他機(jī)器正在執(zhí)行針對(duì)該對(duì)象的同步聲明,原因是,由于競(jìng)態(tài)條件、存儲(chǔ)器不一致將可能引起在參與的機(jī)器上損壞該對(duì)象,而這同樣是同步聲明的并發(fā)執(zhí)行所導(dǎo)致的。因此,當(dāng)DRT確定了該對(duì)象當(dāng)前“已同步”時(shí),DRT通過暫?!癮cquireLockO”操作的執(zhí)行來防止原始代碼塊的執(zhí)行,直到當(dāng)前鎖定的擁有者執(zhí)行了對(duì)應(yīng)的“releaseLockO”操作為止。因此,在執(zhí)行“releaseLockO”操作時(shí),例如通過在同步狀態(tài)共享表中將該對(duì)象標(biāo)記為“未同步”,或可替換地通過按順序釋放在所有其他機(jī)器上獲得的鎖定,當(dāng)前“擁有”鎖定(即正在執(zhí)行同步聲明)的機(jī)器指示其同步聲明的結(jié)束。在這點(diǎn),然后,等待開始執(zhí)行對(duì)應(yīng)的同步聲明的任何其他機(jī)器可通過繼續(xù)執(zhí)行其被推遲(即延遲)的“acquireLockO”操作,例如,在同步狀態(tài)共享表中將自身標(biāo)記為執(zhí)行針對(duì)該對(duì)象的同步聲明,或可替換地在每個(gè)其他機(jī)器上按順序獲得本地鎖定,來要求對(duì)該對(duì)象的鎖定的擁有。這樣,利用DRT,通過改變同步例程(包含開始“monitorenter”和結(jié)束“monitorexti”指令),在應(yīng)用代碼加載入機(jī)器中時(shí)對(duì)其進(jìn)行了修改。所作的修改(以粗體突出顯示)是同步例程執(zhí)行的初始指令。這些添加的指令檢查該鎖定是否已被另一機(jī)器獲得。如果該鎖定尚未被另一機(jī)器獲得,則該機(jī)器的DRT通知所有其他機(jī)器該機(jī)器已獲得鎖定,由此停止其他機(jī)器執(zhí)行針對(duì)該鎖定的同步例程。DRT可以多種方式來記錄機(jī)器的鎖定狀態(tài),例如1.對(duì)應(yīng)于同步例程的入口,DRT單獨(dú)咨詢每個(gè)機(jī)器以確定是否已獲得該鎖定。如果是,則DRT暫停同步例程的執(zhí)行,直到所有其他機(jī)器不再擁有對(duì)該資產(chǎn)或?qū)ο蟮逆i定。否則,DRT執(zhí)行該同步例程??商鎿Q地,2.對(duì)應(yīng)于同步例程的入口,DRT咨詢記錄的共享表(如共享數(shù)據(jù)庫(kù),或每個(gè)參與的機(jī)器上的共享表的拷貝),該共享表指示是否有任何機(jī)器當(dāng)前“擁有”該鎖定。如果是,則DRT暫停在該機(jī)器上執(zhí)行同步例程,直到所有其他機(jī)器不再擁有對(duì)該對(duì)象的鎖定。否則,DRT將該機(jī)器記錄在共享表中(或者多個(gè)共享表中,如果例如在多個(gè)機(jī)器上存在多個(gè)記錄表)作為該鎖定的擁有者,然后執(zhí)行同步例程。相似地,當(dāng)鎖定被釋放時(shí),換言之,當(dāng)同步例程的執(zhí)行結(jié)束時(shí),DRT能以很多可替換的方式將機(jī)器的鎖定狀態(tài)“去掉記錄(un-record)”,例如1.對(duì)應(yīng)于同步例程的出口,DRT單獨(dú)通知每個(gè)其他機(jī)器其不再擁有鎖定??商鎿Q地,2.對(duì)應(yīng)于同步例程的出口,DRT更新記錄共享表中該被鎖定的資產(chǎn)或?qū)ο蟮挠?2錄,這樣該機(jī)器不再被記錄成擁有該鎖定。另外,DRT能以多種可替換的方式將需要獲得鎖定對(duì)象的機(jī)器排隊(duì),例如1.對(duì)應(yīng)于同步例程的入口,DRT通知鎖定對(duì)象的當(dāng)前擁有者,特定機(jī)器欲在當(dāng)前擁有的機(jī)器釋放時(shí)獲得該鎖定。如果沒有其他等待的機(jī)器,則該特定機(jī)器將該特定機(jī)器的興趣存儲(chǔ)在表中,在該鎖定對(duì)象的同步例程結(jié)束的隨后,其通知等待的機(jī)器其可獲得該鎖定對(duì)象,因而開始執(zhí)行其同步例程。2.對(duì)應(yīng)于同步例程的入口,DRT通知該鎖定對(duì)象的當(dāng)前擁有者特定機(jī)器(如M6)將在該機(jī)器(如M4)釋放時(shí)獲取鎖定。如果該機(jī)器M4在咨詢其等待該鎖定對(duì)象的機(jī)器記錄后發(fā)現(xiàn)已經(jīng)有一個(gè)或多個(gè)機(jī)器在等待,則將機(jī)器M6附于想要獲取該鎖定對(duì)象的機(jī)器列表的末尾,或可替換地,將來自M6的請(qǐng)求轉(zhuǎn)發(fā)給第一個(gè)等待的機(jī)器或任何其他等待的機(jī)器,所述第一個(gè)等待的機(jī)器或任何其他等待的機(jī)器又將機(jī)器M6記錄在它們的記錄表中。3.對(duì)應(yīng)于同步例程的入口,DRT將自身記錄在記錄共享表中(例如,存儲(chǔ)在可由所有機(jī)器訪問的共享數(shù)據(jù)庫(kù)中的表、或基本上相似的多個(gè)單獨(dú)的表)。另外,對(duì)應(yīng)于同步例程的出口,DRT可通知其他排隊(duì)的機(jī)器由該機(jī)器以下列可替換的方式來獲取該鎖定,例如1.對(duì)應(yīng)于同步例程的出口,DRT通知正在等待的機(jī)器之一(例如,正在等待的機(jī)器隊(duì)列中的該第一個(gè)機(jī)器)該鎖定已釋放,2.對(duì)應(yīng)于同步例程的出口,DRT通知正在等待的機(jī)器之一(例如,正在等待的機(jī)器隊(duì)列中的該第一個(gè)機(jī)器)該鎖定已釋放,此外,提供整個(gè)機(jī)器隊(duì)列的拷貝(例如,等待該鎖定的第二個(gè)機(jī)器和隨后的機(jī)器)。這樣,第二個(gè)機(jī)器從第一個(gè)機(jī)器繼承正在等待的機(jī)器的列表,并由此在列表中每個(gè)機(jī)器依次獲得并隨后釋放該鎖定時(shí),保證正在等待的機(jī)器隊(duì)列的連續(xù)性。在上述仔細(xì)檢查期間,初始地查找“monitorenter”和“monitorexit”指令(或方法),并且當(dāng)找到時(shí),插入修改的代碼,以得到修改后的同步例程。該修改后的同步例程獲取并釋放鎖定。.執(zhí)行這種修改和加載的有幾種不同的模式。附件D提供了進(jìn)一步的信肩、ο圖26示出了關(guān)于同步的所要遵循的優(yōu)選一般過程。在開始加載161B后,如步驟162B所示,按順序考慮待執(zhí)行的指令,并檢測(cè)所有的同步例程。在JAVA語言中,這些是"monitorenter”和“monitorexit”指令。其他語言使用不同的術(shù)語。在檢測(cè)到同步例程之處,典型地通過將進(jìn)一步的指令插入例程中對(duì)其進(jìn)行修改。可替換地,修改的指令可插入在例程前。一旦完成修改,則繼續(xù)加載過程。如步驟163B所示,所述修改優(yōu)選地采用“acquirelockonallothermachines(在所有機(jī)器上獲取鎖定)”操作和“releaselockonallothermachines(在所有機(jī)器上釋放鎖定)”修改的形式。圖27示出了修改的特定形式。首先,如步驟172B所示,待同步的結(jié)構(gòu)、資產(chǎn)或資源(在JAVA中稱作類或?qū)ο?,?0A、50X-50Y)已被分配名稱或標(biāo)簽,所述名稱或標(biāo)簽可由所有機(jī)器在全局使用。這優(yōu)選地在初始地對(duì)類或?qū)ο筮M(jìn)行初始化時(shí)發(fā)生。這通過服務(wù)器機(jī)器X所維持的表十分方便地完成。該表還包括類或?qū)ο蟮耐綘顟B(tài)。在優(yōu)選實(shí)施例中,該表還包括存儲(chǔ)已請(qǐng)求使用該資產(chǎn)的機(jī)器標(biāo)識(shí)的隊(duì)列設(shè)置。如圖27的步驟173B所示,接下來,“acquirelock”請(qǐng)求被發(fā)送到機(jī)器X,之后,如步驟174B中所示,發(fā)送機(jī)器等待對(duì)鎖定獲取的確認(rèn)。因此,如果全局名稱已經(jīng)被鎖定(即對(duì)應(yīng)資產(chǎn)正在被另一機(jī)器而不是提請(qǐng)獲取該鎖定的機(jī)器所使用),則這意味著所提請(qǐng)的對(duì)象或類的同步例程應(yīng)該暫停,直到該對(duì)象或類被當(dāng)前擁有者解鎖??商鎿Q地,如果全局名稱未被鎖定,則這意味著沒有其他機(jī)器正在使用該類或?qū)ο?,而且立即接收到?duì)鎖定獲取的確認(rèn)。在收到對(duì)鎖定獲取的確認(rèn)后,如步驟175B所示,允許繼續(xù)執(zhí)行同步例程。圖28示出了想要放棄鎖定的應(yīng)用程序執(zhí)行機(jī)器所遵循的過程。步驟181B指示了初始步驟。該提請(qǐng)的機(jī)器的操作由步驟183B、步驟184B臨時(shí)中斷,直到對(duì)應(yīng)于步驟184B,收到來自機(jī)器X的回復(fù),然后如步驟185B所示繼續(xù)執(zhí)行。任選地,且如步驟182B所示,使請(qǐng)求釋放鎖定的機(jī)器在向機(jī)器X作出請(qǐng)求之前查詢?cè)撴i定的“globalname(全局名稱)”。這樣,可獲取并釋放多個(gè)機(jī)器上的多個(gè)鎖定,而不會(huì)彼此干擾。圖29示出了機(jī)器X響應(yīng)于(圖27的/‘a(chǎn)cquirelock”問詢而進(jìn)行的活動(dòng)。當(dāng)在步驟191B接收到“acquirelock”請(qǐng)求后,在步驟192B和193B確定鎖定狀態(tài),如果否-所指定的資源不空閑,在步驟194B將問詢的機(jī)器的標(biāo)識(shí)添加到等待獲取請(qǐng)求的隊(duì)列(或以問詢的機(jī)器的標(biāo)識(shí)來形成等待獲取請(qǐng)求的隊(duì)列)??商鎿Q地,如果回答是肯定的_所指定的資源空閑_則在步驟197B發(fā)送對(duì)應(yīng)的回復(fù)。然后,等待的問詢的機(jī)器能夠通過執(zhí)行圖27的步驟175B來相應(yīng)地執(zhí)行同步例程。除了肯定響應(yīng)以外,還在步驟196B更新共享表,以使全局命名的資產(chǎn)的狀態(tài)改變成“l(fā)ocked(鎖定)”。圖30示出了機(jī)器X響應(yīng)于圖28的“releaselock”請(qǐng)求而進(jìn)行的活動(dòng)。當(dāng)在步驟201接收到“releaselock"請(qǐng)求后,如步驟202所示,機(jī)器X可選地并優(yōu)選地確認(rèn)所述請(qǐng)求釋放鎖定的機(jī)器正是該鎖定的當(dāng)前擁有者。接下來,在步驟203確定隊(duì)列狀態(tài),如果沒有機(jī)器正在等待獲取該鎖定,則如步驟207所示,機(jī)器X在共享表中將該鎖定標(biāo)記為“unowned(未被擁有)”,并如步驟208所示,可選地將對(duì)釋放的確認(rèn)發(fā)送回請(qǐng)求的機(jī)器。這使請(qǐng)求的機(jī)器能夠執(zhí)行圖28的步驟185B。可替換地,如果肯定_即有其他機(jī)器正在等待獲取該鎖定_則如步驟204所示,機(jī)器X將該鎖定標(biāo)記為現(xiàn)在由隊(duì)列中的下一機(jī)器獲取,然后在步驟205將對(duì)鎖定獲取的確認(rèn)發(fā)送到該排隊(duì)的機(jī)器,并因此如步驟206所示,將新鎖定擁有者從等待機(jī)器的隊(duì)列中去除?,F(xiàn)在轉(zhuǎn)到圖31-33,其中示出了兩個(gè)膝上計(jì)算機(jī)101和102。計(jì)算機(jī)101和102不必是相同的,并且實(shí)際上,一個(gè)可以是IBM或IBM-克隆,而另一個(gè)可以是Apple計(jì)算機(jī)。計(jì)算機(jī)101和102具有兩個(gè)屏幕105、115,兩個(gè)鍵盤106、116,但只有單個(gè)鼠標(biāo)107。兩個(gè)機(jī)器101、102借助于單個(gè)同軸線纜或雙絞線線纜314來互連。兩個(gè)簡(jiǎn)單的應(yīng)用程序被下載到機(jī)器101、102的每個(gè)上,如上所述,所述程序在其被加載時(shí)得到修改。在該實(shí)施例中,第一應(yīng)用是簡(jiǎn)單的計(jì)算器程序,并導(dǎo)致計(jì)算器108的圖像顯示在屏幕105上。第二程序是圖形程序,其顯示在矩形框310內(nèi)隨機(jī)移動(dòng)的4個(gè)不同顏色的彩色塊109。同樣,在加載后,框310顯示在屏幕105上。每個(gè)應(yīng)用獨(dú)立運(yùn)行,這樣塊109在屏幕105上隨機(jī)運(yùn)動(dòng),而同時(shí)可選擇(利用鼠標(biāo)107)計(jì)算器108內(nèi)的數(shù)字連同數(shù)學(xué)運(yùn)算符(如加法或乘法),使得計(jì)算器108顯示結(jié)果。鼠標(biāo)107可用來“抓取”框310,并將其移動(dòng)到右邊跨過屏幕105到屏幕115上,以達(dá)到圖32中所示的情形。在該設(shè)置中,計(jì)算器應(yīng)用在機(jī)器101上執(zhí)行,而引起框310的顯示的圖形應(yīng)用在機(jī)器102上執(zhí)行。但是,如圖33所示,可以借助于鼠標(biāo)來將計(jì)算器108拖到右邊,如圖32中所示,以便使計(jì)算器108的一部分分別由屏幕105、115來顯示。相似地,可借助于鼠標(biāo)107將框310拖到左邊,如圖32中所示,以使框310部分顯示在屏幕105、115的每個(gè)上,如圖33中所示。在該配置中,部分計(jì)算器操作在機(jī)器101上執(zhí)行,而部分在機(jī)器102上執(zhí)行,同時(shí)部分圖形應(yīng)用在機(jī)器101上進(jìn)行,而剩余的在機(jī)器102上進(jìn)行。上文僅描述了本發(fā)明的某些實(shí)施例,而對(duì)本領(lǐng)域普通技術(shù)人員顯而易見的是,可在不背離本發(fā)明范圍的情況下對(duì)其進(jìn)行修改。例如,對(duì)JAVA的引用可包括JAVA語言,還可包括JAVA平臺(tái)和架構(gòu)。編程領(lǐng)域的普通技術(shù)人員將意識(shí)到,當(dāng)附加代碼或指令插入現(xiàn)有代碼或指令集中以對(duì)其進(jìn)行修改時(shí),現(xiàn)有代碼或指令集會(huì)需要進(jìn)一步的修改(如通過對(duì)順序的指令重新編號(hào)),以便滿足偏移、分支、屬性和標(biāo)記等。相似地,在JAVA語言中,存儲(chǔ)器位置包括例如字段和數(shù)組類型二者。以上描述討論了字段,而數(shù)組類型所需的改變基本上也是同樣必要的修正。本發(fā)明還可同等地應(yīng)用于與JAVA相似的(包括過程式、宣告式和面向?qū)ο蟮?編程語言,包括Micrsoft.NET平臺(tái)和架構(gòu)(VisualBasic、VisualC/C++和C#)FORTRAN、C/C++、COBOL、BASIC等其中修改了JAVA初始化例程代碼的上述實(shí)施例基于這樣的假設(shè)即每個(gè)機(jī)器Ml...Mn的運(yùn)行時(shí)間系統(tǒng)(S口以C和JAVA編寫的JAVAH0TSP0TVIRTUALMACHINE)或操作系統(tǒng)(例如以C和匯編語言編寫的LINUX)將調(diào)用JAVA初始化例程??梢圆恍薷腏AVA初始化例程,而是對(duì)調(diào)用JAVA初始化例程的LINUX或H0TSP0T例程進(jìn)行修改,這樣,如果已經(jīng)加載了對(duì)象和類,則不調(diào)用JAVA初始化例程。為了包含這樣的設(shè)置,術(shù)語“初始化例程”應(yīng)理解為在其范圍內(nèi)包括JAVA初始化例程以及JAVA初始化例程和調(diào)用或發(fā)起JAVA初始化例程的LINUX或H0TSP0T代碼片段的“組合”二者。其中修改了JAVA終結(jié)化或清理例程代碼的上述實(shí)施例基于這樣的假設(shè)即每個(gè)機(jī)器M1、M2...Mn的運(yùn)行時(shí)間系統(tǒng)(即以C和JAVA編寫的JAVAH0TSP0TVIRTUALMACHINE)或操作系統(tǒng)(例如以C和匯編語言編寫的LINUX)將調(diào)用JAVA終結(jié)化例程??梢圆恍薷腏AVA終結(jié)化例程,而是對(duì)調(diào)用JAVA終結(jié)化例程的LINUX或H0TSP0T例程進(jìn)行修改,這樣,如果不要?jiǎng)h除對(duì)象和類,則不調(diào)用JAVA終結(jié)化例程。為了包含這樣的設(shè)置,術(shù)語“終結(jié)化例程”應(yīng)理解為在其范圍內(nèi)包括JAVA終結(jié)化例程以及JAVA終結(jié)化例程和調(diào)用或發(fā)起JAVA終結(jié)化例程的LINUX或H0TSP0T代碼片段的“組合”二者。其中修改了JAVA同步例程代碼的上述實(shí)施例基于這樣的假設(shè)即每個(gè)機(jī)器Ml、M2...Mn的運(yùn)行時(shí)間系統(tǒng)(SP以C和JAVA編寫的JAVAH0TSP0TVIRTUALMACHINE)或操作系統(tǒng)(例如以C和匯編語言編寫的LINUX)將在本地機(jī)器(如M2)而不是在任何其他機(jī)器(Ml、M3...Mn)上正常獲取鎖定。可以不修改JAVA同步例程,而是對(duì)在本地獲取鎖定的LINUX或H0TSP0T例程進(jìn)行修改,這樣,其對(duì)應(yīng)地在所有其他機(jī)器上獲得鎖定。為了包含這樣的設(shè)置,術(shù)語“同步例程”應(yīng)理解為在其范圍內(nèi)包括JAVA同步例程以及JAVA同步例程和執(zhí)行鎖定獲取和釋放的LINUX或H0TSP0T代碼片段的“組合”二者。在此使用的術(shù)語對(duì)象和類是從JAVA環(huán)境中導(dǎo)出的,且旨在包含從不同環(huán)境如動(dòng)態(tài)鏈接庫(kù)(DLL)或目標(biāo)代碼包或功能單元或存儲(chǔ)器位置導(dǎo)出的相似術(shù)語。在此所用的術(shù)語“包括”(及其語法上的變型)是“具有”或“包含”的包含性的意義,而不是“僅由......來構(gòu)成”的“排他性”的意義。版權(quán)須知該專利說明書包含受版權(quán)保護(hù)的材料。版權(quán)的所有者(即申請(qǐng)人)不反對(duì)為了評(píng)論的目的從公眾可獲得的相關(guān)專利局文件中復(fù)制該專利說明書或相關(guān)材料,但是保留所有的版權(quán)。特別是,在沒有版權(quán)所有者的特別書面許可的情況下,不得將各指令輸入計(jì)算機(jī)中。附件A下面是JAVA語言的程序列表Al.該第一摘錄是修改代碼的部分。其在整個(gè)代碼陣列中搜索,并且在找到putstatic指令(opcode178)時(shí),其實(shí)施所述修改。//STARTbyte[]code=Code_attribute.code;//Bytecodeofagivenmethodina//givenclassfile.intcode_length=Code_attribute.code_length;intDRT=99;//LocationoftheCONSTANTMethodref一infoforthe//DRT.alert()method.for(inti=0;i<code_length;i++){if((code[i]&0xff)==179){//Putstaticinstruction.System,arraycopy(code,i+3,code,i+6,code_length_(i+3));code[i+3]=(byte)184;//Invokestaticinstructionforthe//DRT.alert()method.code[i+4]=(byte)((DRT>>>8)&0xff);code[i+5]=(byte)(DRT&Oxff);}}//ENDA2.該第二摘錄是DRT.alert()方法的部分。這是DRT.alert()方法被調(diào)用時(shí)的主體。//STARTpublicstaticvoidalert(){synchronized{ALERT_L0CK){ALERTLOCK,notify();//AlertsawaitingDRTthreadinthebackground.}}//ENDA3.該第三摘錄是DRTSending的部分。該代碼片段示出了DRT在得到通知后在26單獨(dú)線;程中跨網(wǎng)絡(luò)地發(fā)送值。//STARTMulticastSocketms=DRT.getMulticastSocket();//Themulticastsocket//usedbytheDRTfor//communication.bytenameTag=33;//Thisisthe"nametag"onthenetworkforthis]//field.Fieldfield=modifiedClass.getDeclaredField(“myFieldl");IlStores//thefield//fromthe//modified//class.//Inthisexample,thefieldisabytefield.while(DRT.isRunning()){synchronized(ALERT_L0CK){ALERT_L0CK.waitQ;//TheDRTthreadiswaitingforthealert//methodtobecalled.byte[]b=newbyte[]{nameTag,field.getByte(null)};//Stores//the//nameTag//andthe//value//ofthe//fieldfrom//themodified//classina//buffer.DatagramPacketdp=newDatagramPacket(b,0,b.length);27ms.send(dp);//Sendthebufferoutacrossthenetwork.}}//ENDA4.第四摘錄是DRTreceiving的部分。這是接收DRT在網(wǎng)絡(luò)上發(fā)送的告警的代碼片段。//STARTMulticastSocketms=DRT.getMulticastSocket();//Themulticastsocket//usedbytheDRTfor//comunication.DatagramPacketdp=newDatagramPacket(newbyte[2],0,2);bytenameTag=33;//Thisisthe"nametag"onthenetworkforthis//field.Fieldfield=modifiedClass.getDeclaredField("myFieldl");//Storesthe//fieldfrom//themodified//class.//Inthisexample,thefieldisabytefield.while(DRT.isRunning){ms.receive(dp);//Receivethepreviouslysentbufferfromthenetwork.byte[]b=dp.getDataO;if(b==nameTag){//Checkthenametagsmatch.field.setByte(null,b[l]);//Writethevaluefromthenetworkpacket//intothefieldlocationinmemory.A5.第五摘錄是發(fā)生修改前的示例應(yīng)用。MethodvoidsetValues(int,int)0iload_l1putstatic#3<FieldintstaticValue>4aload_05iload_26putfield#2<FieldintinstanceValue>9returnA6.第六摘錄是與5中相同的示例應(yīng)用已經(jīng)執(zhí)行修改后的情形。修改以粗體突出顯不。MethodvoidsetValues(int,int)0iload」1putstatic#3〈FieldintstaticValue>4ldc#4〈String"example">6iconst—07invokestatic#5〈Methodvoidalert(java.lang.Object,int)>10aload—011iload—212putfield#2〈FieldintinstanceValue>15aload—016iconst—117invokestatic#5〈Methodvoidalert(java.lang.Object,int)>20returnA7.第七摘錄是摘錄5和6中所用的示例應(yīng)用的源代碼。importjava.lang.女;publicclassexample{/女女Sharedstaticfield.女/publicstaticintstaticValue=0;,/女女Sharedinstancefield.女/publicintinstanceValue=0;/**Examplemethodthatwritestomemory(instancefield).*/publicvoidsetValues(inta,intb){staticValue=a;instanceValue=b;ιιA8.第八摘錄是FieldAlert的源代碼,其告警“distrubutedruntime,,以傳播改變的值。importjava.lang.·;importjava.util.~k;importjava.net.~k;importjava.io.~k;publicclassFieldAlert{/**Tableofalerts.*/publicfinalstaticHashtablealerts=newHashtable();/**Objecthandle.*/publicObjectreference=null;/**Tableoffieldalertsforthisobject.*/publicboolean[]fieldAlerts=null;/**Constructor.*/publicFieldAlert(Objecto,intinitialFieldCount){reference=ο;fieldAlerts=newboolean[initialFieldCount];}/-k-kCalledwhenanapplicationmodifiesavalue.(Bothobjectsandclasses)*/publicstaticvoidalert(Objecto,intfieldID){//Lockthealertstable.synchronized(alerts){FieldAlertalert=(FieldAlert)alerts,get(o);if(alert==null){//Thisobjecthasn'tbeenalertedalready,//soaddtoalertstable.alert=newFieldAlert(o,fieldID+1);alerts,put(o,alert);}if(fieldID>=alert.fieldAlerts.length){//0k,enlargefieldAlertsarray.boolean[]b=newboolean[fieldID+1];System,arraycopy(alert.fieldAlerts,0,b,0,alert.fieldAlerts.length);alert.fieldAlerts=b;}//Recordthealert.alert.fieldAlerts[fieldID]=true;//Markaspending.FieldSend.pending=true;//Signalthatthereisoneormore//propagationswaiting.//Finally,notifythewaitingFieldSendthread(s)if(FieldSend.waiting){FieldSend.waiting=false;alerts,notify();}}}}Α9·第九摘錄是FieldSend的源代碼,其將通過FieldAlert告警給其的改變的值傳播。importjava.lang.~k;importjava.lang.reflect.~k;importjava.util.~k;importjava.net.~k;importjava.io.~k;publicclassFieldSendimplementsRunnable{/**Protocolspecificvalues.*/publicfinalstaticintCLOSE=一1;publicfinalstaticintNACK=0;publicfinalstaticintACK=1;publicfinalstaticintPROPAGATEOBJECT=10;publicfinalstaticintPROPAGATECLASS=20;/**FieldAlertnetworkvalues.*/publicfinalstaticStringgroup=System.getProperty("FieldAlert—netwotk—group");publicfinalstaticintport=Integer,parselnt(System.getProperty(“FieldAlert—network—port‘‘));/女女TableofglobalID/sforlocalobjects.(hashcode-to-globalIDmappings)*/publicfinalstaticHashtableobjectToGloballD=newHashtable();/^k^kTableofglobalID'sforlocalc1assnames.(classname-to-globalIDmappings)*/publiefinalstaticHashtablecIassNameToGlobalID=newHashtable()/女女Pending.Trueifapropagationispending.女/publicstaticbooleanpending=false;/**Waiting.TrueiftheFieldSendthread(s)arewaiting.*/publicstaticbooleanwaiting=false;/^k^kBackgroundsendthread.Propagatesvaluesasthisthreadisalertedtotheiralteration.*/publicvoidrun(){System,out.println(/rFieldAlert—network—group=〃+group);System,out.println(/rFieldAlert—network—port=〃+port);31try{//CreateaDatagramSockettosendpropagatedfieldvalues.DatagramSocketdatagramSocket=newDatagramSocket(port,InetAddress.getByName(group));//Next,createthebufferandpacketforalltransmissions.byte[Jbuffer=newbyte[512];//Workinglimitof512bytes//perpacket.DatagramPacketdatagramPacket=newDatagramPacket(buffer,0,buffer,length};while(!Thread,interrupted()){Object[!entries=null;//Lockthealertstable.synchronized(FieldAlert.alerts){//Awaitforanalerttopropagatesomething.while(!pending){waiting=true;FieldAlert.alerts,wait();waiting=false;}pending=false;entries=FieldAlert.alerts.entrySet().toArray();//Clearalertsoncewehavecopiedthem.FieldAlert.alerts,clear();}//Processeachobjectalertinturn.for(inti=0;i<entries,length;i++){FieldAlertalert=(FieldAlert)entries[i];intindex=0;datagramPacket.setLength(buffer,length);Objectreference=null;if(alert,referenceinstanceofString){//PROPAGATE—CLASSfieldoperation.buffer[index++]=(byte)((PROPAGATECLASS>>24)&0xff)buffer[index++]=(byte)((PROPAGATECLASS>>16)&0xff)buffer[index++]=(byte)((PROPAGATECLASS>>8)&0xff)buffer[index++]=(byte)((PROPAGATECLASS>>0)&0xff)Stringname=(String)alert,reference;intlength=name,length();buffer[index++]=(byte)((length>>24)&0xff);buffer[index++]=(byte)((length>>16)&0xff);buffer[index++]=(byte)((length>>8)&0xff);buffer[index++]=(byte)((length>>0)&0xff);byte[]bytes=name.getBytes();System,arraycopy(bytes,0,buffer,index,length);index+=length;}else{//PROPAGATEOBJECTfieldoperation.buffer[index++]=(byte)((pROPAGATEOBJECT>>24)&0xff);buffer[index++]=(byte)((PROPAGATEOBJECT>>16)&0xff);buffer[index++]=(byte)((PROPAGATEOBJECT>>8)&0kff);buffer[index++]=(byte)((PROPAGATEOBJECT>>0)&0xff);intglobalID=((Integer)objectToGloballD.get(alert,reference)).intValue();buffer[index++]=(byte)((globalID>>24)&0xff);buffer[index++]=(byte)((globalID>>16)&0xff);buffer[index++]=(byte)((globalID>>8)&0xff);buffer[index++]=(byte)((globalID>>0)&0xff);reference=alert,reference;}//Usereflectiontogetatableoffieldsthatcorrespondto//thefieldindexesusedinternally.Field[]fields=null;if(reference==null){fields=FieldLoader.IoadClass((String)alert,reference).getDeclaredFields();}else{fields=alert,reference.getClass().getDeclaredFields();}//NowencodeinbatchmodethefieldlD/valuepairs.for(intj=0;j<alert.fieldAlerts.length;j++){if(alert.fieldAlerts[j]==false)continue;buffer[index++]=(byte)((j>>24)&0xff);buffer[index++]=(byte)((j>>16)&0xff);buffer[index++]=(byte)((j>>8)&0xff);buffer[index++]=(byte)((j>>0)&0xff);33//Encodevalue.Classtype=fields[j].getType();if(type==Boolean.TYPE){buffer[index++]=(byte)(fields[j].getBoolean(reference)?1:0);}elseif(type==Byte.TYPE){buffer[index++]=fields[j].getByte(reference);}elseif(type==Short.TYPE){shortν=fields[j].getshort(reference);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Character.TYPE){charν=fields[j].getChar(reference);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Integer.TYPE){intν=fields[j].getlnt(reference);buffer[index++]=(byte)((v>>24)&0xff);buffer[index++]=(byte)((v>>16)&0xff);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Float.TYPE){intν=Float,fIoatToIntBits{fields[j].getFloat(reference));buffer[index++]=(byte)((v>>24)&0xff);buffer[index++]=(byte)((v>>16)&0xff);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Long.TYPE){longν=fields[j].getLong(reference);buffer[index++]=(byte)((v>>56)&0xff);buffer[index++]=(byte)((v>>48)&0xff);buffer[index++]=(byte)((v>>40)&0xff);buffer[index++]=(byte)((v>>32)&0xff);buffer[index++]=(byte)((v>>24)&0xff);buffer[index++]=(byte)((v>>16)&0xff);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Double.TYPE){34type.改變的值longν=Double.doubleToLongBits(fields[j].getDouble(reference))buffer[index++]buffer[index++]buffer[index++]buffer[index++]=(byte)((v>>56)&0xff)=(byte)((v>>48)&0xff)=(byte)((v>>40)&0xff)=(byte)((v>>32)&0xff)buffer[index++]=(byte)((v>>24)&0xff);buffer[index++]=(byte)((v>>16)&0xff);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}else{thrownewAssertionError("Unsupported//Nowsetthelengthofthedatagrampacket.datagramPacket.setLength(index);//Nowsendthepacket.datagramSocket.send(datagramPacket);}catch(Exceptione){thrownewAssertionError('Exception"+e.toString())A10.第十摘錄是FieldReceive的源代碼,其接收經(jīng)由FieldSend發(fā)送的所傳播的-kimportjava.lang.~k;importjava.lang.reflect,importjava.util.~k;importjava.net.~k;importjava.io.~k;publicclassFieldReceiveimplementsRunnable{■k//**Protocolspecificvalues.publicfinalstaticintCLOSE=publicfinalstaticintNACK=)publicfinalstaticintACK=1port‘’publicfinalstaticintPR0PAGATE_0BJECT=10;publicfinalstaticintPROPAGATECLASS=20;/**FieldAlertnetworkvalues.*/publicfinalstaticStringgroup=System.getProperty(〃FieldAlert_network_group");publicfinalstaticintport=Integer,parselnt(System.getProperty("FieIdAlert_network_))/TableofglobalID/sforlocalobjects.(globalID-to-hasbcodemappings)*/publicfinalstaticHashtableglobalIDToObject=newHashtable();/女女TableofglobalID'sforlocalclassnames.(globalID-to-classnamemappings)*/publicfinalstaticHashtableglobalIDToClassName=newHashtable();/女女Calledwhenanapplicationistoacguirealock.女/publicvoidrun(){System,out.println("FieldAlert—network—group-"+group);System,out.println(/rFieldAlert—network—Port="+port);try{//CreateaDatagramSockettosendpropagatedfieldvaluesfromMulticastSocketmulticastSocket=newMulticastSocket(port);multicastSocket.joinGroup(InetAddress.getByName(group));//Next,createthebufferandpacketfor.alltransmissions.byte[Jbuffer=newbyte[512];//Workinglimitof512//bytesperpacket.DatagramPacketdatagramPacket=newDatagramPacket(buffer,O,buffer.length);while(!Thread,interrupted()){//Makesuretoresetlength.datagramPacket.setLength(buffer,length);//Receivethenextavailablepacket.multicastSocket.receive(datagramPacket);intindex=0,length=datagramPacket.getLength();//Decodethecommand.intcommand=(int)(((buffer[index++]&0xff)<<24)I((buffer[index++]&0xff)<<16)I((buffer[index++]&0xff)<<8)36(buffer[index++]&0xff));if(command==PROPAGATEOBJECT){//Propagateoperationfor.//objectfields.//Decodeglobalid.intglobalID=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));//Now,needtoresolvetheobjectinquestion.Objectreference=globalIDToObject.get(newInteger(globalID));//Next,getthearrayoffieldsforthisobject.Field[]fields=reference.getClass().getDeclaredFields();while(index<length){//Decodethefieldid.intfieldID=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));//Determinevaluelengthbasedoncorrespondingfield//type.Fieldfield=fields[fieldID];Classtype=field.getType();if(type==Boolean.TYPE){booleanν=(buffer[index++]==1true:false);field.setBoolean(reference,v);}elseif(type.==Byte.TYPE){byteν=buffer,[index++];field.setByte(reference,v);}elseif(type==Short.TYPE){shortν=(short)(((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setShort(reference,v);}elseif(type==Character.TYPE){charν=(char)(((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setChar(reference,v);}elseif(type==Integer.TYPE){intν=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)I((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setlnt(reference,v);}elseif(type==Float.TYPE){intv=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)I((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setFloat(reference,Float.intBitsToFloat(v));}elseif(type==Long.TYPE){longν=(long)(((buffer[index++]&0xff)<<56)((buffer[index++]&0xff)<<48)((buffer[index++]&0xff)<<40)((buffer[index++]&0xff)<<32)((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setLong(reference,v);}elseif(type==Double.TYPE){longν=(long)(((buffer[index++]&0xff)<<56)((buffer[index++]&0xff)<<48)((buffer[index++]&0xff)<<40)((buffer[index++]&0xff)<<32)((buffer[index++]&0xff)<<24)I((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setDouble(reference,Double.IongBitsToDouble(v)};}else{thrownewAssertionError("Unsupportedtype.");}}}elseif(command==PROPAGATECLASS){//Propagateanupdate//toclassfields.//Decodetheclassname.intnameLength=(int)(((buffer[index++]&0xff)<<24)I((buffer[index++]&0xff)<<16)I((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));Stringname=newString(buffer,index,nameLength);index+=nameLength;//Next,getthearrayoffieldsforthisclass.Field[]fields=FieldLoader.IoadClass(name).getDeclaredFields();//Decodeallbatchedfieldsincludedinthispropagation//packet.while(index<length){//Decodethefieldid.intfieldID=(int)(((buffer[index++]&0xff)<<24)((buffer[index++].&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));//Determinefieldtypetodeterminevaluelength.Fieldfield=fields[fieldID];Classtype=field.getType();if(type==Boolean.TYPE){booleanν=(buffer[index++]==1?true:false);field.setBoolean(null,v);}elseif(type==Byte.TYPE){byteν=buffer[index++];field.setByte(null,v);}elseif(type==Short.TYPE){shortν=(short)(((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setShort(null,ν);}elseif(type==Character.TYPE){charν=(char)(((buffer[index++]&0xff)<<8)(buffer[index++]&0xff)};field.setChar(null,ν);}elseif(type==Integer.TYPE){intν=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field,setlnt(null,ν);}elseif(type==Float.TYPE){390730]intν=(int)(((buffer[index++]&0xff)<<24)0731]((buffer[index++]&0xff)<<16)0732]I((buffer[index++]&0xff)<<8)0733](buffer[index++]&0xff));0734]field.setFloat(null,Float.intBitsToFloat(v));0735]}elseif(type==Long.TYPE){0736]longν=(long)(((buffer[index++]&0xff)<<56)0737]((buffer[index++]&0xff)<<48)0738]I((buffer[index++]&0xff)<<40)0739]I((buffer[index++]&0xff)<<32)0740]I((buffer[index++]&0xff)<<24)0741]((buffer[index++]&0xff)<<16)0742]I((buffer[index++]&0xff)<<8)0743](buffer[index++]&0xff));0744]field.setLong(null,ν);0745]}elseif(type==Double.TYPE){0746]longν=(long)(((buffer[index++]&0xff)<<56)0747]I((buffer[index++]&0xff)<<48)0748]I((buffer[index++]&0xff)<<40)0749]I((buffer[index++]&0xff)<<32)0750]I((buffer[index++]&0xff)<<24)0751]((buffer[index++]&0xff)<<16)0752]I((buffer[index++]&0xff)<<8)0753]I(buffer[index++]&0xff));0754]field.setDouble(null,Double.IongBitsToDouble(v));0755]}else{//Unsupportedfieldtype.0756]thrownewAssertionError("Unsupportedtype.");0757]}0758]}0759]}0760]}0761]}catch(Exceptione){0762]thrownewAssertionError("Exception:"+e.toString());0763]}0764]}0765]}0766]All.FieldLoader.java0767]該摘錄是FieldLoader的源代碼,其在加載應(yīng)用時(shí)對(duì)其進(jìn)行修改。0768]importjava.lang.~k;importjava.io.*;importjava.net.*;publicclassFieldLoaderextendsURLClassLoader{publicFieldLoader(URL[Juris){super(urls);}protectedClassfindClass(Stringname)throwsClassNotFoundException{ClassFilecf=null;try{BufferedInputStreamin=newBufferedInputStream(findResource{name,replace('.','/').concat(“.class“)).openStreamO);cf=newClassFile(in);}catch(Exceptione){thrownewClassNotFoundException(e.toStringO);}//Class-widepointerstotheIdcandalertindex.intldcindex=_1;intalertindex=_1;for(inti=O;i<cf.methods_count;i++){for(intj=O;j<cf.methods[i].attributes_count;j++){.if(!(cf.methods[i].attributes[j]instanceofCode_attribute))continue;Code_attributeca=(Code_attribute)cf.methods[i].attributes[j];booleanchanged=false;for(intζ=O;z<ca.code,length;z++){if((ca.code[z]&0xff)==179){//OpcodeforaPUTSTATIC//instruction.changed=true;//Thecodebelowonlysupportsfieldsinthisclass.//Thus,firstoff,checkthatthisfieldislocaltothis//class.CONSTANT—Fieldref—infofi=(CONSTANT—Fieldref—info)cf.constant—pool[(int)(((ca.code[z][l]&0xff)41<<8)(ca.code[ζ][2]&0xff))];CONSTANT_Class_infoci=(CONSTANT_Class_info)cf.constant_pool[fi.class_index];StringcIassName=cf.constant_pool[ci.name_index].toString();if(!name,equals(className)){thrownewAssertionError("Thiscodeonlysupportsfields""localtothisclass");}//0k,nowsearchforthefieldsnameandindex.intindex=O;CONSTANT_NameAndType_infoni=(CONSTANT_NameAndType_info)cf.constant_pool[fi.name_and_type_index];StringfieldName=cf.constant_pool[ni.name_index].toString();for(inta=O;a<cf.fields_count;a++){Stringfn=cf.constant_pool{cf.fields[a].name_index].toString();if(fieldName.equals(fn)){index=a;break;}}//Next,realignthecodearray,makingroomforthe//insertions.byte口[]code2=newbyte[ca.code,length+3][];System,arraycopy(ca.code,0,code2,0,z+1);System,arraycopy(ca.code,z+1,code2,z+4,ca.code,length-(z+1));ca.code=code2;//Next,inserttheLDC_ffinstruction.if(ldcindex==-1){C0NSTANT_String_infocsi=newC0NSTANT_String_info(ci.name_index);cp_info[]cpi=newcp_info[cf.constant_pool.length+1];System,arraycopy(cf.constant_pool,0,cpi,0,cf.constant_pool.length);cpi[cpi.length-1]=csi;Idcindex=cpi.Iength-I;cf.constant_pool=cpi;cf.constant_pool_count++;}ca.code[z+l]=newbyte[3];ca.code[z+1]=(byte)19;ca.code[z+1][1]=(byte)((ldcindex>>8)&0xff);ca.code[z+1][2]=(byte)(ldcindex&Oxff);//Next,inserttheSIPUSHinstruction.ca.code[z+2]=newbyte[3];ca.code[z+2]=(byte)17;ca.code[z+2][1]=(byte)((index>>8)&0xff);ca.code[z+2][2]=(byte)(index&Oxff);//Finally,insertthe.INV0KESTATICinstruction.if(alertindex==-1){//Thisisthefirsttimethisclassisencourteringtheul;(cl;ul;I)V");43//alertinstruction,sohavetoaddittotheconstant//pool.cp_info[]cpi=newcp_info[cf.constant_pool.length+6];System,arraycopy(cf.constant_pool,0,cpi,0,cf.constant_pool.length);cf.constant_pool=cpi;cf.constant_pool_count+=6;C0NSTANT_Utf8_infoul=newC0NSTANT_Utf8_info("FieldAlert");cf.constant_pool[cf.constant_pool.length-6]=C0NSTANT_Class_infocl=newC0NSTANT_Class_infocf.constant_pool_count_6);cf.constant_pool[cf.constant_pool.length-5]=ul=newC0NSTANT_Utf8_info("alert");cf.constant_pool[cf.constant_pool.length-4]=ul=newC0NSTANT_Utf8_info("(Ljava/lang/Object;cf.constant_pool[cf.constant_pool.length-3]=ul;CONSTANT_NameAndType_infonl=newCONSTANT_NameAndType_info{cf.constant_pool.length-4,cf.constant_pool.Iength-3);cf.constant_pool[cf.constant_pool.length-2]=nl;CONSTANT_Methodref_infoml=newCONSTANT_Methodref_info{cf.constant_pool.length-5,cf.constant_pool.Iength-2);cf.constant_pool[cf.constant_pool.length-1]=ml;alertindex=cf.constant_pool.length-1;}ca.code[z+3]=newbyte[3];ca.code[z+3]=(byte)184;ca.code[z+3][1]=(byte)((alertindex>>8)&0xff);ca.code[z+3][2]=(byte)(alertindex&Oxff);//Andlastly,increasetheCODE_LENGTHandATTRIBUTE_LENGTH//values.ca.code_length+=9;ca.attribute_length+=9;}}//Ifwechangedthismethod,thenincreasethestacksizebyone.if(changed){ca.max_stack++;//Justtomakesure.}}}try{ByteArrayOutputStreamout=newByteArrayOutputStream();44cf.serialize(out);byte[]b=out.toByteArray();returndefineClass(name,b,0,b·length);}catch(Exceptione){thrownewClassNotFoundException(name);}}}fields"A12.Attribute—info,javafields"用于表示ClassFile內(nèi)的attribute—info結(jié)構(gòu)的Convience類。importjava.lang.*;importjava.io.*;/**Thisabstractclassrepresentsalltypesofattribute_info女thatareusedintheJVMspecifications.±*Allnewattribute_infosubclassesaretoalwaysinheritfromthis*class.*/publicabstractclassattributeinfo{publicintattributenameindex;publicintattribute_length;/**Thisisusedbysubclassestoregisterthemselves*totheirparentclassFile.*/attribute—info(ClassFilecf){}/女女UsedduringinputserializationbyClassFileonly.女/attribute_info(ClassFilecf,DataInputStreamin)throwsIOException{attributenameindex=in.readChar();attribute—length=in.readlnt();}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{out.writeChar(attribute—name_index);out.writelnt(attributelength);}/**Thisclassrepresentsanunknownattribute_infothat45*thiscurrentversionofclassfilespecificationdoes*notunderstand.女/publicfinalstaticclassUnknownextendsattribute_info{byte[]info;/**UsedduringinputserializationbyClassFileonly.*/Unknown(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);info=newbyte[attributelength];in.read(info,0,attribute_lemgth);ι/**usedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{ByteArrayOutputStreambaos=newByteArrayOutputStream();super,serialize(out);out.write(info,0,attribute_length);ιιιA13.ClassFile.java用于表示ClassFile結(jié)構(gòu)的Convience類。importjava.lang.~k;importjava.io.~k;importjava.util.;/**TheClassFilefollowsverbatimfromtheJVMspecification.*/publicfinalclassClassFile{publicintmagic;publicintminor_version;publicintmajor_version;publicintconstant_pool_count;publiccp_infο[]constant_pool;publicintaccess—flags;publicintthis_class;publicintsuper_class;publicintinterfaces_count;publicint[]interfaces;publicintfieldscount;757677787980818283publicfield_info[]fields;publicintmethods_count;publicmethod_info[]methods;publicintattributes_count;publicattribute—info[]attributes;/~k-kConstructor.Takesinabytestreamrepresentationandtransforms*eachoftheattributesintheClassFileintoobjectstoallowfor*easiermanipulation.女/publicClassFile(InputStreamins)throwsIOException{DataInputStreamin=(insinstanceofDataInputStream?(DataInputStream)ins:newDataInputStream(ins));magic=in.readlnt();minor_version=in.readChar();[1000]major_version=in.readChar();[1001]constant—pool_count=in.readChar();[1002]constant—pool=newcp_info[constant—pool_count];[1003]for(inti=1;i<constant—pool_count;i++){[1004]in.mark(l);[1005]ints=in.read();[1006]in.reset();[1007]switch(s){[1008]case1:[1009]constant一pool[i]=newCONSTANT一Utf8—info(this,in);[1010]break;[1011]case3:[1012]constant—pool[i]=newC0NSTANT_Integer_info(this,in);[1013]break;[1014]case4:[1015]constant—pool[i]=newCONSTANT—Float_infο(this,in);[1016]break;[1017]case5:[1018]constant—pool[i]=newC0NSTANT_Long—info(this,47in);i++;break;case6:constant一pool[i]=newCONSTANT_Double_info(this,in);i++;break;case7:constant一pool[i]=newC0NSTANT_Class_info(this,in);break;case8:constant一pool[i]=newC0NSTANT_String_info(this,in);break;case9:constant一pool[i]=newCONSTANT一Fieldref一info(this,in);break;case10:constant一pool[i]=newCONSTANT一Methodref一info(this,in);break;case11:constant_pool[i]=newCONSTANT_InterfaceMethodref_info(this,in);break;case12:constant一pool[i]=newCONSTANT_NameAndType_info(this,in);break;default:thrownewClassFormatError("InvalidConstantpoolTag");}}access—flags=in.readChar();this_class=in.readChar();super_class=in.readChar();interfaces_count=in.readChar();interfaces=newint[interfaces_count];for(inti=0;i<interfaces_count;i++)interfaces[i]=in.readChar();fields_count=in.readChar();fields=newfield—info{fieldscount];for(inti=0;i<fields_count;i++){fields[i]=newfield—info(this,in);ιmethods_count=in.readChar();methods=newmethod—info[methods_count];for(inti=0;i<methods_count;i++){methods[i]=newmethod—info(this,in);ιattributes_count=in.readChar();attributes=newattribute_info.[attributescount];for(inti=0;i<attributes_count;i++){in.mark(2);Strings=constant—pool[in.readChar()].toString()in.reset();if(s.equals('SourceFile"))attributes[i]=newSourceFile_attribute(this,in)elseif(s.equals{“Deprecated"))attributes[i]=newDeprecated—attribute(this,in)elseif(s.equals{“InnerClasses“))attributes[i]=newInnerClasses_attribute(this,in)elseattributes[i]=newattribute_info.Unknown(this,in)/**SerializestheClassFileobjectintoabytestream.*publicvoidserialize(OutputStreamo)throwsIOException{DataOutputStreamout=(oinstanceofDataOutputStream?(DataOutputStream)ο:newDataOutputStream(o));out.writelnt(magic);out.writeChar(minor_version);out.writeChar(major_version);out.writeChar(constant—pool—count);491091]1092]1093]1094]1095]1096]1097]1098]1099]1100]1101]1102]1103]1104]1105]1106]1107]1108]1109]1110]1111]1112]1113]1114]1115]1116]1117]1118]1119]1120]1121]1122]1123]1124]1125]1126]1127]1128]1129]for(inti=1;i<constant_pool_count;i++){constant—pool[i]·serialize(out);if(constant_pool[i]instanceofC0NSTANT_Long_info||constant_pool[i]instanceofC0NSTANT_Doub1e_info)i++;}out.writeChar(access_flags);out.writeChar(this_class);out.writeChar(super_class);out.writeChar(interfaces—count);for(inti=0;i<interfaces_count;i++)out.writeChar(interfaces[i]);out.writeChar(fields_count);for(inti=0;i<fields_count;i++)fields[i]·serialize(out);out:writeChar(methods_count);for(inti=0;i<methods_count;i++)methods[i].serialize(out);out.writeChar(attributes—count);for(inti=0;i<attributes_count;i++)attributes[i].serialize(out);//Flushtheoutputstreamjusttomakesure,out.flush0;A14.Code—attribute,java用于表示ClassFile內(nèi)的Code—attribute結(jié)構(gòu)的Convience類。importjava.util.女;importjava.lang.^;importjava.io.*;/±±女Thecode[]isstoredasa2Darray.女/publicfinalclassCode_attributeextendsattribute_info{publicintmax_stack;publicint_max_locals;publicintcode—length;publicbyte[][]code;publicintexception—table—length;publicexception—table[]exception—table;50[1130]publicintattributes_count;publicattribute_info[]attributes;/女女Internalclassthathandlestheexceptiontable.女/publicfinalstaticclassexception—table{publicintstsrt—pc;publicintend—pc;publicinthandler—pc;publicintcatch—type;}/**Constructorcalledonlybymethod—info·*/Code_attribute(ClassFilecf,intani,intal,intms,intml,intcl,byte[][]cd,intetl,exception_table[]et,intac,attribute—info[]a){super(cf);attribute—name_index=ani;attribute—length=al;max—stack=ms;max_locals=ml;code—length=cl;code_=cd;exception—table—length=etl;exception—table=et;attributes_count=ac;attributes=a;}/女女UsedduringinputserializationbyClassFileonly.女/Code_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);max_stack=in.readChar();max_locals=in.readChar();code—length=in.readlnt();code=newbyte[code_length][];inti=0;for(intpos=0;pos<code—length;i++){in.mark(l);ints=in.read();in.reset();switch(s){51[1169]case16:case18:case21:case22:case23:case24:case25:case54:case55:case56:case57:case58:case169:case188:case196:code[i]=newbyte[2];break;case17:case19:case20:case132:case153:case154:case155:case156:case157:case158:case159:case160:case161:case162:case163:case164:case165:case166:case167:case168:case178:case179:52[1208]case180:case181:case182:case183:case184:case187:case189:case192:case193:case198:case199:case209:code[i]=newbyte[3];break;case197:code[i]=newbyte[4];break;case185:case200:case201:code[i]=newbyte[5];break;case170:{intpad=3_(pos%4);in.mark(pad+13);//highbytein.skipBytes(pad+5);//lowbyteintlow=in.readlnt();code[i]=newbyte[pad+13+((in.readlnt()-low+1)*4)];in.reset();break;}case171:{intpad=3-(pos%4);in.mark(pad+9);in.skipBytes(pad+5);code[i]=newbyte[pad+9+(in.readlnt()*8)];in.reset();break;}default:[1247[1248[1249[1250[1251[1252[1253[1254[1255[1256[1257[1258[1259[1260[1261[1262[1263[1264[1265[1266[1267[1268[1269[1270[1271[1272[1273[1274[1275[1276[1277[1278[1279[1280[1281[1282[1283[1284[1285code[i]=newbyte[1];in.read(code[i],0,code[i].length);pos+=code[i].length;//adjustthearraytothenewsizeandstorethesizebyte[][]temp=newbyte[i][];System,arraycopy(code,0,temp,0,i);code=temp;exception—table—length=in.readChar();exception_tabIe=newCode_attribute.exception_tabIe[exception_table_length]for(i=0;i<exception_table_length;i++){exception_table[i]=newexception_tabIe();exception—table[i]·start_pc=in.readChar();exception_table[i].end_Pc=in.readChar();exception_table[i].handler_pc=in.readChar();exception—table[i]·catch—type=in.readChar();}attributescount=in.readChar();attributes=newattributeinfo[attributescount];for(i=0;i<attributescount;i++){in.mark(2);Strings=cf.constant—pool[in.readChar()].toString();in.reset();if(s.equals(〃LineNumberTable〃))attributes[i]=newLineNumberTableattribute(cf,in);elseif(s.equals{“LocalVariableTable/r))attributes[i]=newLocalVariableTableattribute(cf,in)elseattributes[i]=newattributeinfo.Unknown(cf,in)/**UsedduringoutputserializationbyClassFileonly.女/voidserialize(DataOutputStreamout)throwsIOException{attribute—length=12+code—length+(exception—table—length*8);1286]for(inti=0;i<attributes_count;i++)1287]attribute—length+=attributes[i].attribute—length+61288]super,serialize(out);1289]out.writeChar(max_stack);1290]out.writeChar(max_locals);1291]out.writelnt(code_length);1292]for(inti=0,pos=0;pos<code—length;i++){1293]out.write(code[i],0,code[i].length);1294]pos+=code[i].length;1295]}1296]out.writeChar(exception—table—length);1297]for(inti=0;i<exception—table—length;i++){1298]out.writeChar(exception—table[i]·start—pc);1299]out.writeChar(exception—table[i]·end—pc);1300]out.writeChar(exception—table[i].handler—pc);1301]out.writeChar(exception—table[i]·catch—type);1302]ι1303]out.writeChar(attributes_count);1304]for(inti=0;i<attributes_count;i++)1305]attributes[i].serialize(out);1306]}1307]}1308]A15.CONSTANT—Class—info,java1309]用于表示ClassFile內(nèi)的C0NSTANT_Class—info結(jié)構(gòu)的Convience類。1310]importjava.lang.*;1311]importjava.io.女;1312]1313]/女女Classsubtypeofaconstantpoolentry.女/1314]publicfina:_classCONSTANT_Class_infoextendscp_info{1315]/**Theindextothenameofthisclass.*/1316]publicintname_index=0;1317]/**Convenienceconstructor.1318]女/1319]publicC0NSTANT_Class_info(intindex){1320]tag=7;1321]name_index=index;1322]}1323]/**UsedduringinputserializationbyClassFileonly.*1324]C0NSTANT_Class_info(ClassFilecf,DataInputStreamin)551325]1326]1327]1328]1329]1330]1331]1332]1333]1334]1335]1336]throwsIOException{super(cf,in);if(tag!=7)thrownewClassFormatError();name_index=in.readChar();/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{out.writeByte(tag);out.writeChar(name_index);1337]}1338]A16.CONSTANTDouble_info.java1339]用于表示ClassFile內(nèi)的CONSTANTDoubleinfo結(jié)構(gòu)的Convience類。1340]importjava.lang.~k;1341]importjava.io.*;1342]/-k-kDoublesubtypeofaconstantpoolentry.~k/1343]publicfinalclassCONSTANT_Doub1e_infοextendscp_info{1344]/-A--A-Theactualvalue./1345]publicdoublebytes;1346]publicCONSTANT_Double_info(doubled){1347]tag=6;1348]bytes=d;1349]}1350]/-k-kUsedduringinputserializationbyClassFileonly.~k/1351]CONSTANT_Double_info(ClassFilecf,DataInputStreamin)1352]throwsIOException{1353]super{cf,in);1354]if(tag!=6)1355]thrownewClassFormatError(};1356]bytes=in.readDouble();1357]}1358]/**UsedduringoutputserializationbyClassFileonly.*/1359]voidserialize{DataOutputStreamout)1360]throwsIOException{1361]out.writeByte(tag);1362]out.writeDouble(bytes);1363]long1=Double.doubleToLongBits(bytes);56[1364]}}A17.CONSTANT—Fieldref—info,java用于表示ClassFile內(nèi)的CONSTANT—Fieldref—info結(jié)構(gòu)的Convience類。importjava.lang.*;importjava.io.*;/**Fieldrefsubtypeofaconstantpoolentry.*/publicfinalclassCONSTANT—Fieldref—infoextendscp_info{/**Theindextotheclassthatthisfieldisreferencingto.*publicintclass_index;/**Thenameandtypeindexthisfieldifreferencingto.*/publicintname_and_type_index;/**Convenienceconstructor.*/publicCONSTANT—Fieldref—info(intclass_index,intname_and—type—index){tag=9;this.class_index=class_index;this.name_and_type_index=name_and_type_index;}/女女UsedduringinputserializationbyClassFileonly.女/C0NSTANT_Fieldref_info(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);if(tag!=9)thrownewClassFormatError();class_index=in.readChar();name_and_type_index=in.readChar();}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException[out.writeByte(tag);out.writeChar(class_index);out.writeChar(name_and_type_index);}}A18.CONSTANT—Float—info,java57[1401]用于表示ClassFile內(nèi)的CONSTANT_Float_info結(jié)構(gòu)的Convience類。importjava.lang.~k;importjava.io.~k;/**Floatsubtypeofaconstantpoolentry.*/publicfinalclassC0NSTANT_Float_infoextendscp_info{/**Theactualvalue.*/publicfloatbytes;publicC0NSTANT_Float_info(floatf){tag=4;bytes=f;}/-k-kUsedduringinputserializationbyClassFileonly.*/C0NSTANT_Float_info(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);if(tag!=4)thrownewClassFormatError();bytes=in.readFloat();}/**UsedduringoutputserializationbyClassFileonly.*/publicvoidserialize(DataOutputStreamout)throwsIOException{out.writeByte(4);out.writeFloat(bytes);}}A19.C0NSTANT_Integer_info.java用于表示ClassFile內(nèi)的C0NSTANT_Integer—info結(jié)構(gòu)的Convience類。importjava.lang.~k;importjava.io.~k;/-A--A-Integersubtypeofaconstantpoolentry.~k/publicfinalclassC0NSTANT_Integer_infoextendscp_info{/**Theactualvalue.*/publicintbytes;publicC0NSTANT_Integer_info(intb){tag=3;bytes=b;}/**UsedduringinputserializationbyClassFileonly.*/1440]CONSTANT_Integer_info(ClassFilecf,DataInputStreamin)1441]throwsIOException{1442]super(cf,in);1443]if(tag!=3)1444]thrownewClassFormatError();1445]bytes=in.readlnt();1446]}1447]/**UsedduringoutputserializationbyClassFileonly.*/1448]publicvoidserialize(DataOutputStreamout)1449]throwsIOException{1450]out.writeByte(tag);1451]out.writelnt(bytes);1452]}}A20.CONSTANT_InterfaceMethodref_info.java用于表示ClassFiIe內(nèi)的CONSTANT—InterfaceMethodref_infο結(jié)構(gòu)的Convience類。importjava.lang.女;importjava.io.*;I±±InterfaceMethodrefsubtypeofaconstantpoolentry.1459]*/1460]publicfinalclassCONSTANT_InterfaceMethodref_infoextendscp_info{1461]I±±Theindextotheclassthatthisfieldisreferencingto.女/1462]publicintclass_index;1463]/**Thenameandtypeindexthisfieldifreferencingto.*/1464]publicintname_and_type_index;1465]publicCONSTANT_InterfaceMethodref_info(intclass_index,1466]intname_and_type_index)1467]tag=11;1468]this.class_index=class_index;1469]this.name_and_type_index=name_and_type_index;1470]}1471]/**UsedduringinputserializationbyClassFileonly.*/1472]CONSTANT_InterfaceMethodref_info(ClassFilecf,DataInputStreamin)1473]throwsIOException{1474]super(cf,in);1475]if(tag!=11)1476]thrownewClassFormatError();591477]class—index=in.readChar();1478]name_and_type_index=in.readChar();1479]}1480]/**UsedduringoutputserializationbyClassFileonly.*/1481]voidserialize(DataOutputStreamout)1482]throwsIOException{1483]out.writeByte(tag);1484]out.writeChar(class_index);1485]out.writeChar(name_and_type_index);1486]}1487]}1488]A21.CONSTANT—Long—info,java1489]用于表示ClassFile內(nèi)的CONSTANT—Long—info結(jié)構(gòu)的Convience類。1490]importjava.lang.女;1491]importjava.io.*;1492]/女女Longsubtypeofaconstantpoolentry.女/1493]publicfinalclassC0NSTANT_Long—infoextendscp_info{1494]/女女Theactualvalue.女/1495]publiclongbytes;1496]publicC0NSTANT_Long_info(longb){1497]tag=5;1498]bytes=b;1499]}1500]/**UsedduringinputserializationbyClassFileonly.*/1501]C0NSTANT_Long_info(ClassFilecf,DataInputStreamin)1502]throwsIOException{1503]super(cf,in);1504]if(tag!=5)1505]thrownewClassFormatError();1506]bytes=in.readLong();1507]}1508]/**UsedduringoutputserializationbyClassFileonly.*/1509]voidserialize(DataOutputStreamout)1510]throwsIOException{1511]out.writeByte(tag);1512]out.writeLong(bytes);1513]}1514]}1515]A22.CONSTANT_Methodref_info.java60[1516]用于表示ClassFile內(nèi)的CONSTANT—Methodref—info結(jié)構(gòu)的Convience類。importjava.lang.*;importjava.io.*;/女女Methodrefsubtypeofaconstantpoolentry.*/publicfinalclassCONSTANT—Methodref—infoextendscp_info{/女女Theindextotheclassthatthisfieldisreferencingto.女/publicintclass_index;/**Thenameandtypeindexthisfieldifreferencingto.*/publicintname_and_type_index;publicCONSTANT—Methodref—info(intclass_index,intname—and—type_index){tag=10;this.class_index=class_index;this.name_and_type_index=name_and_type_index;}/女女UsedduringinputserializationbyClassFileonly.女/C0NSTANT_Methodref_info(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);if(tag!=10)thrownewClassFormatError();class_index=in.readChar();name_and_type_index=in.readChar();}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{out.writeByte(tag);out.writeChar(class_index);out.writeChar(name_and_type_index);}1548]}1549]A23.CONSTANT—NameAndType_infο·java1550]用于表示ClassFile內(nèi)的CONSTANT—NameAndType—info結(jié)構(gòu)的Convience類。1551]importjava.io.*;1552]importjava.lang.*;[1553]/**NameAndTypesubtypeofaconstantpoolentry.[1554]女/[1555]publicfinalclassCONSTANT—NameAndType_infoextendscp_info{[1556]/**TheindextotheUtf8thatcontainsthename.*/[1557]publicintname_index;[1558]/**TheindexfotheUtf8thatconstainsthesignature.女/[1559]publicintdescriptor—index;[1560]publicCONSTANT—NameAndType_info(intname_index,intdescriptor—index}{[1561]tag=12;[1562]this.name_index=name_index;[1563]this,descriptor—index=descriptor—index;[1564]ι[1565]/**UsedduringinputserializationbyClassFileonly.*/[1566]CONSTANT—NameAndType_info(ClassFilecf,DataInputStreamin)[1567]throwsIOException{[1568]super(cf,in);[1569]if(tag!=12)[1570]thrownewClassFormatError();[1571]name—index=in.readChar();[1572]descriptor_index=in.readChar();[1573]ι[1574]/**UsedduringoutputserializationbyClassFileonly.女/[1575]voidserialize(DataOutputStreamout)[1576]throwsIOException{[1577]out.writeByte(tag);[1578]out.writeChar(name_index);[1579]out.writeChar(descriptor—index);[1580]ι[1581]ι[1582]A24.CONSTANT_String_info.java[1583]用于表示ClassFile內(nèi)的CONSTANT_String_info結(jié)構(gòu)的Convience類ο[1584]importjava.lang.~k;[1585]importjava.io.~k;[1586]/-k-kStringsubtypeofaconstantpoolentry.[1587]女/[1588]publicfinalclassCONSTANT_String—infoextendscp_info{[1589]/女女Theindextotheactualvalueofthestring.女/[1590]publicintstring—index;1591]publicCONSTANT_String_info(intvalue){1592]tag=8;1593]string—index=value;1594]}1595]I±±ONLYTOBEUSEDBYCLASSFILE!±/1596]publicCONSTANT_String—info(ClassFilecf,DataInputStreamin)1597]throwsIOException{1598]super(cf,in);1599]if(tag!=8)1600]thrownewClassFormatError();1601]string—index=in.readChar();1602]}1603]/**Outputserialization,ONLYTOBEUSEDBYCLASSFILE!*/1604]publicvoidserialize(DataOutputStreamout)1605]throwsIOException{1606]out.writeByte(tag);1607]out.writeChar(string—index);1608]}1609]}1610]A25.CONSTANT—Utf8—info,java1611]用于表示ClassFile內(nèi)的CONSTANT—Utf8—info結(jié)構(gòu)的Convience類。1612]importjava.io.*;1613]importjava.lang.*;1614]/**Utf8subtypeofaconstantpoolentry.1615]*WeinternallyrepresenttheUtf8infobytearray1616]asaString.1617]±/1618]publicfinalclassC0NSTANT_Utf8_infoextendscp_info{1619]/±±Lengthofthebytearray.女/1620]publicintlength;1621]/±±Theactualbytes,representedbyaString.女/1622]publicStringbytes;1623]/**Thisconstructorshouldbeusedforthepurpose1624]*ofpartcreation.Itdoesnotsettheparent1625]*ClassFilereference.1626]*/1627]publicCONSTANT—Utf8—info(Strings){1628]tag=1;1629]length=s.length();63[1630]bytes=s;}/女女UsedduringinputserializationbyClassFileonly.女/publicC0NSTANT_Utf8_info(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);if(tag!=1)thrownewClassFormatError();length=in.readChar();byte[]b=newbyte[length];in.read(b,O,length);//WARNING:Stringconstructorisdeprecated.bytes=newString(b,0,length);}/**UsedduringoutputserializationbyClassFileonly.*/publicvoidserialize(OataOutputStreamout)throwsIOException{out.writeByte(tag);out.writeChar(length);//WARNING:HandlingofStringcoversionheremightbeproblematic.out.writeBytes(bytes);}publicStringtoString(){returnbytes;}}A26.ConstantValue_attribute.javaflgT^^ClassFile內(nèi)白勺ConstantValue_attribute@豐勾白勺Convience#。importjava.lang.*;importjava.io.*;/**Attributethatallowsforinitializationofstaticvariablesin*classes.Thisattributewillonlyresideinafieldinfo_struct.*/publicfinalclassConstantValue_attributeextendsattribute_info{publicintconstantvalue_index;publicConstantValue_attribute(ClassFilecf,intani,intal,intcvi){super(cf);64[1667]attribute—name_index=ani;attribute—length=al;constantvalue_index=cvi;}publicConstantValue_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);constantvalue_index=in.readChar();}publicvoidserialize(DataOutputStreamout)throwsIOException{attribute_length=2;super,serialize(out);out.writeChar(constantvalue—index);}[1682]}A27.cp_info.java用于表示ClassFile內(nèi)的cp—info結(jié)構(gòu)的Convience類。importjava.lang.*;importjava.io.*;/**Representsthecommoninterfaceofallconstantpoolparts*thatallspecificconstantpoolitemsmustinheritfrom.±*/publicabstractclasscp_info{/女女Thetypetagthatsignifieswhatkindofconstantpool*itemitis*/publicinttag;/**Usedforserializationoftheobjectbackintoabytestream.女/abstractvoidserialize(DataOutputStreamout)throwsIOException;/**Defaultconstructor.Simplydoesnothing.*/publiccp—info(){}/**ConstructorsimplytakesintheClassFileasareferenceto*it'sparent*/publiccp_info(ClassFilecf){}/女女UsedduringinputserializationbyClassFileonly.女/651704]cp_info(ClassFilecf,DataInputStreamin)1705]throwsIOException{1706]tag=in.readUnsignedByte();1707]}}A28.Deprecated—attribute·javaflgT^^ClassFile白勺Deprecated一attribute@豐勾白勺Convience#。importjava.lang.*;importjava.io.*;/**AfixattributedthatcanbelocatedeitherintheClassFile,1714]*field—infoorthemethod—infoattribute.Markdeprecatedto1715]*indicatethatthemethod,classorfieldhasbeensuperceded.1716]±/1717]publicfinalclassDeprecated—attributeextendsattribute_info{1718]publicDeprecated—attribute(ClassFilecf,intani,intal){1719]super(cf);1720]attribute—name_index=ani;1721]attribute_length=al;1722]}1723]/±±UsedduringinputserializationbyClassFileonly.女/1724]Deprecated—attribute(ClassFilecf,DataInputStreamin)1725]throwsIOException{1726]super(cf,in);1727]}1728]}1729]A29.ExCeptions_attribute.java1730]flgT^^ClassFile白勺Exceptions—attribute@豐勾白勺Convience#。1731]importjava.lang.*;1732]importjava.io.*;1733]/**Thisisthestructwheretheexceptionstablearelocated.1734]±<br><br>1735]±Thisattributecanonlyappearonceinamethod—infostruct.1736]*/1737]publicfinalclassExceptions_attributeextendsattribute_info{1738]publicintnumber_of—exceptions;1739]publicint[]exception—index—table;1740]publicExceptions_attribute(ClassFilecf,intani,intal,intnoe,1741]int[]eit){1742]super(cf);[1743]attribute—name_index=ani;attribute_length=al;number_of—exceptions=noe;exception—index—table=eit;}/女女UsedduringinputserializationbyClassFileonly.女/Exceptions_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);number_of—exceptions=in.readChar();exception_index_table=newint[numberofexceptions];for(inti=0;i<number_of—exceptions;i++)exception_index_table[i]=in.readChar();}/**UsedduringoutputserializationbyClassFileonly.*/publicvoidserialize(DataOutputStreamout)throwsIOException{attribute_length=2+(number_of—exceptions*2);super,serialize(out);out.writeChar(number_of—exceptions);for(inti=0;i<number_of—exceptions;i++)out.writeChar(exception—index—table[i]);}}A30.field—info,java用于表示ClassFile內(nèi)的field—info結(jié)構(gòu)的Convience類。importjava.lang.*;importjava.io.*;1771]/**Representsthefield—infostructureasspecifiedintheJVM1772]specification.1773]*/1774]publicfinalclassfield—info{1775]publicintaccess_flags;1776]publicintname_index;1777]publicintdescriptor—index;1778]publicintattributes_count;1779]publicattribute_info[]attributes;1780]/**Convenienceconstructor.*/1781]publicfield—info(ClassFilecf,intflags,intni,intdi){6717821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819access_flags=flags;nameindex=ni;descriptor_index=di;attributes_count=0;attributes=newattribute_info;}/女女Constructorcalledonlyduringtheserializationprocess.*<br><br>*Thisisintentionallyleftaspackageprotectedaswe*shouldnotnormallycallthisconstructordirectly.*<br><br>Warning:thehandlingofIenisnotcorrect(afterStrings女/field—info(ClassFilecf,DataInputStreamin)throwsIOException{access_flags=in.readChar();name—index=in.readChar();descriptor_index=in.readChar();attributes_count=in.readChar();attributes=newattribute_info[attributes_count];for(inti=0;i<attributes_count;i++){in.mark(2);Strings=cf.constant—pool[in.readChar()].toString();in.reset();if(s.equals(〃ConstantValue〃))attributes[i]=newConstantValue_attribute(cf,in);elseif(s.equals{“Synthetic"))attributes[i]=newSynthetic_attribute(cf,in);elseif(s.equals{“Deprecated/r))attributes[i]=newDeprecated—attribute(cf,in);elseattributes[i]=newattribute_info.Unknown(cf,in);/**Toserializethecontentsintotheoutputformat.女/publicvoidserialize(DataOutputStreamout)throwsIOException{68[1820]out.writeChar(access_flags);out.writeChar(name_index);out.writeChar(descriptor—index);out.writeChar(attributes_count);for(inti=0;i<attributes_count;i++)attributes[i].serialize(out);}}A31.InnerClasses_attribute.javaflgT^^ClassFile內(nèi)白勺InnerClasses_attribute@豐勾白勺Convience#。importjava.lang.*;importjava.io.*;/**Avariablelengthstructurethatcontainsinformationaboutan*innerclassofthisclass.*/publicfinalclassInnerClasses_attributeextendsattribute_info{publicintnumber_of—classes;publicclasses[]classes;publicfinalstaticclassclasses{intinner_class_info_index;intouter_class_info_index;intinner—name_index;intinner_class_access_flags;}publicInnerClasses_attribute(ClassFilecf,intani,intal,intnoc,classes[]c){super(cf);attribute—name_index=ani;attribute_length=al;number_of—classes=noc;classes=c;}/女女UsedduringinputserializationbyClassFileonly.女/InnerClasses_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);number_of—classes=in.readChar();classes=newInnerClasses_attribute,classes[number_ofclasses];69[1858]for(inti=0;i<number_of—classes;i++){[1859]classes[i]=newclasses();[1860]classes[i].inner_class_info_index=in.readChar();[1861]classes[i].outer_class_info_index=in.readChar();[1862]classes[i].inner—name_index=in.readChar();[1863]classes[i].inner_class_access_flags=in.readChar();[1864]ι[1865]ι[1866]/**UsedduringoutputserializationbyClassFileonly.*/[1867]publicvoidserialize(DataOutputStreamout}[1868]throwsIOException{[1869]attribute_length=2+(number_of—classes*8);[1870]super.serialize(out);[1871]out.writeChar(number_of—classes);[1872]for(inti=0;i<number_of—classes;i++){[1873]out.writeChar(classes[i].inner_class_info_index);[1874]out.writeChar(classes[i].outer_class_info_index);[1875]out.writeChar(classes[i].inner—name_index);[1876]out.writeChar(classes[i].inner_class_access_flags);[1877]ι[1878]ι[1879]}[1880]A32.LineNumberTable_attribute.jaVa[1881]fflT^^ClassFile白勺LineNumberTable_attributeg豐勾白勺Convienceg。[1882]importjava.lang.^;[1883]importjava.io.*;[1884]/女-kDetermineswhichlineofthebinarycoderelatestothe[1885]*correspondingsourcecode.[1886]/[1887]publicfinalclassLineNumberTable_attributeextendsattribute_info{[1888]publicintline—number_table_length;[1889]publicline—number_table[]line—number_table;[1890]publicfinalstaticclassline—number_table{[1891]intstart—pc;[1892]intline—number;[1893]ι[1894]publicLineNumberTable_attribute(ClassFilecf,intani,intal,intIntl,[1895]line—number_table[]Int){[1896]super(cf);attribute—name_index=ani;attribute_length=al;line—number—table—length=Intl;line—number—table=Int;}/女女UsedduringinputserializationbyClassFileonly.女/LineNumberTable_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);line—number_table_length=in.readChar();line—number—table=newLineNumberTable_attribute.1ine_number_table[1ine_number_table_length];for(inti=0;i<line—number—table—length;i++){line—number—table[i]=newline—number_table();line—number_table[i]·start—pc=in.readChar();line—number_table[i]·line—number=in.readChar();}}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{attribute_length=2+(line—number_table_length*4);super,serialize(out);out.writeChar(line—number_table_length);for(inti=0;i<line—number—table—length;i++){out·writeChar(line—number—table[i]·start—pc);out·writeChar(line—number—table[i]·line—number);}}}A33.LocalVariableTable—attribute·javaflgT^^ClassFile白勺LocalVariableTable_attribute@豐勾白勺Convience#。importjava.lang.*;importjava.io.*;/**Usedbydebuggertofindouthowthesourcefilelinenumberislinked女tothebinarycode.Ithasmanytoonecorrespondenceandisfound71ininfo{al,tablet]*theCode_attribute.女/publicfinalclassLocalVariableTable_attributeextendsattribute—publicintlocal_variable_table_length;publiclocal_variable_table[]local_variable_table;publicfinalstaticclasslocal_variable_table{intstart—pc;intlength;intname_index;intdescriptor_index;intindex;ιpublicLocalVariableTable_attribute(ClassFilecf,intani,intintlvtl,localvariablelvt){super(cf);attribute—name_index=ani;attribute_length=al;local—variable—table—length=lvtl;local—variable—table=Ivt;)/**UsedduringinputserializationbyClassFileonly.*/LocalVariableTable_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);local_variable_table_length=in.readChar();local—variable—table=newLoca1VariableTable_attribute.local_variable_table[local_variable_table—length];for(inti=O;i<local—variable—table—length;i++){local—variable—table[i]=newlocal—variable—table();local_variable_table[i].start—pc=in.readChar();local_variable_table[i].length=in.readChar();local_variable_table[i].name_index=in.readChar();72[1967]local—variable—table[i].descriptor—index=in.readChar();local_variable_table[i].index=in.readChar();}}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException(attribute—length=2+(local—variable—table—length女10);super,serialize(out);out.writeChar(local_variable_table_length);for(inti=0;i<local—variable—table—length;i++){out·writeChar(local—variable—table[i]·start—pc);out.writeChar(local_variable_table[i].length);out.writeChar(local_variable_table[i].name_index);out·writeChar(local—variable—table[i]·descriptor—index);out·writeChar(local—variable—table[i]·index);}}}A34.methOd—info,java用于表示ClassFile內(nèi)的method—info結(jié)構(gòu)的COnvienCe類。importjava.lang.*;importjava.io.*;/**Thisfollowsthemethod—infointheJVMspecification.*/publicfinalclassmethod—info{publicintaccess_flags;publicintname_index;publicintdescriptor—index;publicintattributes_count;publicattribute_info[]attributes;/**Constructor.Createsamethod—info,initializesitwith女theflagsset,andthenameanddescriptorindexesgiven.*Anewuninitializedcodeattributeisalsocreated,andstored*inthe<i>code</invariable.*/publicmethod—info(ClassFilecf,intflags,intni,intdi,intac,attribute_info[la)(access_flags=flags;name_index=ni;[2006]descriptor_index=di;[2007]attributes_count=ac;[2008]attributes=a;[2009]}[2010]/**Thismethodcreatesamethod—infofromthecurrentpointerinthe[2011]女datastream.Onlycalledbyduringtheserializationofacomplete[2012]*ClassFilefromabytestream,notnormallyinvokeddirectly.[2013]女/[2014]method—info(ClassFilecf,DataInputStreamin)[2015]throwsIOException{[2016]access_flags=in.readChar();[2017]name—index=in.readChar();[2018]descriptor_index=in.readChar();[2019]attributes_count=in.readChar();[2020]attributes=newattribute_info[attributes_count];[2021]for(inti=0;i<attributes_count;i++){[2022]in.mark(2);[2023]Strings=cf.constant—pool[in.readChar()].toString();[2024]in.reset();[2025]if(s.equals(,rCode"))[2026]attributes[i]=newCode_attribute(cf,in);[2027]elseif(s.equals{“Exceptions'7))[2028]attributes[i]=newExceptions_attribute(cf,in);[2029]elseif(s.equals{“Synthetie/r))[2030]attributes[i]=newSynthetic_attribute(cf,in);[2031]elseif(s.equals{“Deprecated/r))[2032]attributes[i]=newDeprecated—attribute(cf,in);[2033]else[2034]attributes[i]=newattribute_info.Unknown(cf,in);[2035]ι[2036]ι[2037]/女女Outputserializationofthemethod—infotoabytearray.[2038]*Notnormallyinvokeddirectly.[2039]女/[2040]publicvoidserialize(DataOutputStreamout)[2041]throwsIOException{[2042]out.writeChar(access_flags);74[2044]out.writeChar(descriptor—index);out.writechar(attributes—count);for(inti=0;i<attributes_count;i++)attributes[i].serialize(out);}}A35.SourceFile—attribute·javaffiT^^ClassFile白勺SourceFile_attribute@豐勾白勺Convience#。importjava.lang.*;importjava.io.*;/**ASourceFileattributeisanoptionalfixed—lengthattributein*theattributestable.OnlylocatedintheClassFilestructonly±once.±/publicfinalclassSourceFile_attributeextendsattribute_info{publicintsourcefile—index;publicSourceFile_attribute(ClassFilecf,intani,intal,intsfi){super(cf);attribute—name_index=ani;attribute_length=al;sourcefile—index=sfi;}/±±UsedduringinputserializationbyClassFileonly.女/SourceFile_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);sourcefile—index=in.readChar();}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{attribute_length=2;super,serialize(out);out.writeChar(sourcefile—index);}}A36.Synthetic—attribute·javaflgT^^ClassFile白勺Synthetic—attribute@豐勾白勺Convience#。752082]importjava.lang.~k;2083]importjava.io.~k;2084]/**Asyntheticattributeindicatesthatthisclassdoesnothave2085]*ageneratedcodesource.Itislikelytoimplythatthecode2086]~kisgeneratedbymachinemeansratherthancodeddirectly.This2087]~kattributecanappearintheclassfile,method_infoorfield_info.2088]*Itisfixedlength.2089]女/2090]publicfinalclassSynthetic_attributeextendsattribute_info{2091]publicSynthetic_attribute(ClassFilecf,intani,intal){2092]super(cf);2093]attribute—name_index=ani;2094]attribute_length=al;2095]ι2096]/**UsedduringoutputserializationbyClassFileonly.*/2097]Synthetic_attribute(ClassFilecf,DataInputStreamin)2098]throwsIOException{2099]super(cf,in);2100]}2101]}2102]附件B2103]Bl2104]Method<clinit>2105]0new#2〈Classtest>2106]3dup2107]4invokespecial#3〈Methodtest()>2108]7putstatic#4〈FieldtestthisTest>2109]10return2110]B22111]Method<clinit>2112]0invokestatic#3〈MethodbooleanisAlreadyLoaded()>2113]3ifeq72114]6return2115]7new#5〈Classtest〉2116]10dup2117]11invokespecial#6〈Methodtest()>2118]14putstatic#7〈FieldtestthisTeSt>2119]17return2120]B32121]Method<init>2122]0al0ad_02123]1invokespecial#l<Methodjava.lang.Object()>2124]4aload_02125]5invokestatic#2<MethodlongcurrentTimeMillis()>2126]8putfield#3<Fieldlongtimestamp>2127]11return2128]B42129]Method<init>2130]0aload_02131]1invokespecial#l<Methodjava.lang.Object()>2132]4invokestatic#2<MethodbooleanisAlreadyLoaded()>2133]7ifeq112134]10return2135]11aload_02136]12invokestatic#4<MethodlongcurrentTimeMillis()>2137]15putfield#5<Fieldlongtimestamp>2138]18return2139]B52140]Method<clinit>2141]0ldc#2<String"test")2142]2invokestatic#3<MethodbooleanisAlreadyLoaded(java.lang.String))2143]5ifeq92144]8return2145]9new#5<Classtest)2146]12dup2147]13invokespecial#6<Methodtest()>2148]16putstatic#7<FieldtestthisTest>2149]19return2150]B62151]Method<init>2152]0aload02153]1invokespecial#l<Methodjava.lang.Object()>2154]4aload_02155]5invokestatic#2<MethodbooleanisAlreadyLoaded(java.lang.Object))2156]8ifeq122157]11return2158]12aload_02159]13invokestatic#4<MethodlongcurrentTimeMillis()>7773/105頁(yè)[2161][2162]port"))[2181][2182],,,16putfield#5<Fieldlongtimestamp>19return附件B7該摘錄是InitClient的源代碼,其針對(duì)相關(guān)類或?qū)ο蟮某跏蓟癄顟B(tài)來查詢"initialisationserver”。importjava.lang.女;importjava.util.女;importjava.net.女;importjava.io.*;publicclassInitClient{/**Protocolspecificvalues.*/CLOSE=-1;NACK=0;ACK=1;INITIALIZE—CLASS=10;INITIALIZE—OBJECT=2o;/**Initservernetworkvalues.*/publicfinalstaticStringserverAddress=System.getProperty(〃InitServer—network—address〃);publicfinalstaticintserverPort=Integer,parselnt(System.getProperty(“InitServer_network_publicfinalstaticintpublicfinalstaticintpublicfinalstaticintpublicfinalstaticintpublicfinalstaticint/女女TableofglobalID/sforlocalobjects.(hashcode-to-globalIDmappings)*/publicfinalstaticHashtablehashCodeToGlobalID=newHashtable();/**Calledwhenaobjectisbeinginitialized.*/publicstaticbooleanisAlreadyLoaded(Objecto){//Firstofall,weneedtoresolvetheglobalID//forobject'ο'.TodothisweusethehashCodeToGlobalID//table.intglobalID=((Integer)hashCodeToGlobalID·get(o)).intValue();try{//Next,wewanttoconnecttothelnitServer,whichwillinformus//oftheinitializationstatusofthisobject.Socketsocket=newSocket(serverAddress,serverPort);DataOutputStreamout=newDataOutputStream(socket.getOutputStream());DataInputStreamin=newDataInputStream(socket.getlnputStream());78[2198]//Ok,nowsendtheserializedrequesttothelnitServer.out.writelnt(INITIALIZE—OBJECT);out.writelnt(globalID);out.flush();//Nowwaitforthereply.intstatus=in.readlnt();//Thisisablockingcall.Sowe//willwaituntiltheremoteside//sendssomething.if(status==NACK){thrownewAssertionError(”Negativeacknowledgement.Requestfailed.”);}elseif(status!=ACK){thrownewAssertionError(〃Unknownacknowledgement“+status+".Requestfailed.");}//Next,readina32bitargumentwhichisthecountofprevious//initializations.intcount=in.readlnt();//Ifthecountisequalto0,thenthisisthefirst//initialization,andhenceisAlreadyLoadedshouldbefalse.//Ifhowever,thecountisgreaterthan0,thenthisisalready//initialized,andthusisAlreadyLoadedshouldbetrue.booleanisAlreadyLoaded=(count==Ofalse:true);//Closedowntheconnection.out.writelnt(CLOSE);out.flush();out.close();in.close();socket,close();//Makesuretoclosethesocket.//ReturnthevalueoftheisAlreadyLoadedvariable.returnisAlreadyLoaded;}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}/**Calledwhenaclassisbeinginitialized.*/publicstaticbooleanisAlreadyLoaded(Stringname){try(//Firstofall,wewanttoconnecttothelnitServer,whichwill[2237]//infornusoftheinitializationstatusofthisclass.Socketsocket=newSocket(serverAddress,serverPort);DataOutputStreamout=newDataOutputStream(socket.getOutputStream());DataInputStreamin=newDataInputStream(socket.getlnputStream());//0k,nowsendtheserializedrequesttotheInitServer.out.writelnt(INITIALIZE—CLASS);out.writelnt(name,length());//A32bitlengthargumentof//theStringname.out.write(name.getBytes(),0,name,length());//Thebyte-//encoded//Stringname.out.flush();//Nowwaitforthereply.intstatus=in.readlnt();//Thisisablockingcall.Sowe//willwaituntiltheremoteside//sendssomething.if(status==NACK){thrownewAssertionError{”Negativeacknowledgement.Requestfailed.”);)elseif(status!=ACK){thrownewAssertionError(〃Unknownacknowledgement:“+status+".Requestfailed.");}//Next,readina32bitargumentwhichisthecountofthe//previousintializations·intcount=in.readlnt();//Ifthecountisequalto0,thenthisisthefirst//initialization,andhenceisAlreadyLoadedshouldbefalse.//Ifhowever,thecountisgreaterthan0,thenthisisalready//loaded,andthusisAlreadyLoadedshouldbetrue.booleanisAlreadyLoaded=(count==0false:true};//Closedowntheconnection.out.writelnt(CLOSE);out.flush();out.close();in.closeQ;80[2275]socket,close();//Makesuretoclosethesocket.//ReturnthevalueoftheisAlreadyLoadedvariable.returnisAlreadyLoaded;}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}}附件B8該摘錄是InitServer的源代碼,其接收InitClient的初始化狀態(tài)查詢,并作出響應(yīng)將對(duì)應(yīng)的狀態(tài)返回。importjava.lang.*;importjava.util.*;importjava.net.*;importjava.io.*;publicclassInitServerimplementsRunnable{/**Protocolspecificvalues*/publicfinalstaticintCLOSE=-1;[2291]publicfinalstaticintNACK=0;[2292]publicfinalstaticintACK=1;[2293]publicfinalstaticintlNITIALIZE—CLASS=10;[2294]publicfinalstaticintINITIALIZE_0BJECT=20/**InitServernetworkvalues.*/publicfinalstaticintserverPort=20001;/**Tableofinitializationrecords.*/publicfinalstaticHashtableinitializations=newHashtable();/**Privateinput/outputobjects.*/privateSocketsocket=null;privateDataOutputStreamoutputStream;privateDataInputStreaminputStream;privateStringaddress;publicstaticvoidmain(String[]s)throwsException{System,out.println("InitServer—network—address=“+InetAddress.getLocalHost().getHostAddress());System,out.println("InitServer—network—port=“+serverPort);//Createaserversockettoacceptincominginitializationoperation//connections.ServerSocketserverSocket=newServerSocket(serverPort);81[2312]while(!Thread,interrupted()){//Blockuntilanincominginitializationoperationconnection.Socketsocket=serverSocket.accept();//CreateanewinstanceofInitservertomanagethis//initializationoperationconnection.newThread(newInitServer(socket)).start();}}/**Construetor·InitializethisnewlnitServerinstancewithnecessaryresourcesforoperation.*/publicInitServer(Sockets){socket=s;try{outputStream=newDataOutputStream(s.getOutputStream());inputStream=newDataInputStream(s.getlnputStreamO);address=s.getlnetAddress().getHostAddress();}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}/**Maincodebody.Decodeincominginitializationoperationrequestsandexecuteaccordingly.*/publicvoidrun(){try{//Allcommandsareimplementedas32bitintegers.//Legalcommandsarelistedinthe〃protocolspecificvalues"http://fieldsabove.intcommand=inputStream.readlnt();//ContinueprocessingcommandsuntilaCLOSEoperation.while(command!=CLOSE){if(command==INITIALIZE—CLASS){//Thisisan//INITIALIZE—CLASS//operation.//Readina32bitlengthfield'1‘,andaStringnamefor//thisclassoflength'?!ntlength=inputStream.readlnt();82[2348]byte[]b=newbyte[length];inputStream.read(b,0,b.length);StringcIassName=newString(b,0,length);//Synchronizeontheinitializationstableinorderto//ensurethread-safety.synchronized(initializations){//Locatethepreviousinitializationsentryforthis//class,ifany.Integerentry=(Integer)initializations·get(className);if(entry==null){//Thisisanunknownclassso//updatethetablewitha//correspondingentry.initializations,put(className,newlnteger(1));//sendapositiveacknowledgementtoInitClient,//togetherwiththecountofpreviousinitializations//ofthisclass-whichinthiscaseofanunknown//classmustbe0.outputStream.writelnt(ACK);outputStream.writelnt(0);outputStream.flush();}else(//Thisisaknownclass,soupdate//thecountofinitializations.initializations,put(className,newInteger(entry.intValue()+1));//SendapositiveacknowledgementtoInitClient,//togetherwiththecountofpreviousinitializtions//ofthisclass-whichinthiscaseofaknownclass//mustbethevalueof〃entry.intValue()〃.outputStream.writelnt(ACK);outputStream.writelnt(entry.intValue());outputStream.flush();}}}elseif(command==INITIALIZE—OBJECT){//Thisisan//INITIALIZEOBJECT//operation.//ReadintheglobalIDoftheobjecttobeinitialized.[2385]intglobalID=inputStream.readlnt();//Synchronizeontheinitializationstableinorderto//ensurethread-safety.synchronized(initializations){//Locatethepreviousinitializationsentryforthis//object,ifany.Integerentry=(Integer)initializations,get(newlnteger(globalID));if(entry==null){//Thisisanunknownobjectso//updatethetablewitha//correspondingentry.initializations,put(newInteger(globalID),newlnteger(1));//SendapositiveacknowledgementtoInitClient,//togetherwiththecountofpreviousinitializations//ofthisobject—whichinthiscaseofanunknown//objectmustbe0.outputStream.writelnt(ACK);outputStream.writelnt(0);outputStream.flush();}else{//Thisisaknownobjectsoupdatethe//countofinitializations.initializations,put(newlnteger(qloballD},newlnteger(entry.intValue()+1));//SendapositiveacknowledgementtoInitClient,//togetherwiththecountofpreviousinitializations//ofthisobject-whichinthiscaseofaknown//objectmustbevalue"entry.intValue()“.outputStream.writelnt(ACK);outputStream.writelnt(entry.intValue());outputStream.flush();}}}else{//Unknowncommand.thrownewAssertionError(〃Unknowncommand.Operationfailed.〃);}//Readinthenextcommand.command=inputStream.readlnt();84[2424]}}catch(Exceptione){thrownewAssertionError("Exception:"+e.toString());}finally{try{//Closingdown.Cleanupthisconnection.outputStream.flush();outputStream.close();inputStream.close();socket,close();}catch(ThrowabIet){t.printStackTrace();}//Garbagethesereferences.outputStream=null;inputStream=null;socket=null;}}}附件B9該摘錄是附件B的示例之前/之后所使用的示例應(yīng)用的源代碼。importjava.lang.女;publicclassexample{/**Sharedstaticfield.*/publicstaticexamplecurrentExample;/女女Sharedinstancefield.女/publiclongtimestamp;/**Staticintializer.(clinit)*/static{currentExample=newexample();}/**Instanceintializer(init)*/publicexample(){timestamp=System.currentTimeMiIlis();}}附件BlOInitLoader.java[2463]該摘錄是InitLoader的源代碼,其在加載應(yīng)用時(shí)對(duì)其進(jìn)行修改。importjava.lang.女;importjava.io.*;importjava.net.*;publicclassInitLoaderextendsURLClassLoader{publicInitLoader(URL[]urls){super(urls);}protectedClassfindClass(Stringname)throwsClassNotFoundException{ClassFilecf=null;try{BufferedInputStreamin=newBufferedInputStream(findResource(name,replace(f.‘,'Γ).concat(".class")).openStreamO);cf=newClassFile(in);}catch(Exceptione){thrownewClassNotFoundException(e.toStringO);}for(inti=O;i〈cf.methods—count;i++){;//Findthe〈clinit>method—infostruct.StringmethodName=cf.constant—pool[cf.methods[i].name_index].toString();if(!methodName.equals(〃<clinit>〃)){continue;}//NowfindtheCode_attributeforthe<clinit>method.for(intj=O;j<cf.methods[i].attributes—count;j++){if(!(cf.methods[i].attributes[j]instanceofCode—attribute))continue;Code_attributeca=(Code_attribute)cf.methods[i].attributes[j];//First,shiftthecode[]downby‘instructions,byte[][]code2=newbyte[ca.code,length+4][];System,arraycopy(ca.code,O,code2,4,ca.code,length);ca.code=code2;//Thenenlargetheconstant—poolby7items.cp_info[]cpi=newcp_info[cf.constant—pool,length+7];System,arraycopy(cf.constant—pool,0,cpi,O,cf.constant—pool·length);[2500]cf.constant—pool=cpi;[2501]cf.constant—pool_count+=7;[2502]//Nowaddtheconstantpoolitemsfortheseinstructions,[2503]starting[2504]//withString.[2505]CONSTANT—String—infocsi=newCONSTANT—String—info([2506]((C0NSTANT_C1ass_info)cf.constant_pool[cf.this_class]).name_index)[2507]cf.constant—pool[cf·constant—pool·length-7]=csi;[2508]//NowaddtheUTFforclass.[2509]C0NSTANT_Utf8_info_ul=newC0NSTANT_Utf8_infoCInitClient");[2510]cf.constant—pool[cf·constant—pool·length-6]=ul;[2511]//NowaddtheCLAsSforthepreviousUTF.[2512]CONSTANT—Class—infocl=[2513]newC0NSTANT_Class_info(cf.constant—pool,lenqth-6);[2514]cf.constant—pool[cf.constant—pool·length-5]=cl;[2515]//NextaddthefirstUTFforNameAndType.[2516]ul=newCONSTANT—Utf8—info("isAlreadyLoaded");[2517]cf.constant—pool[cf·constant—pool·length-4]=ul;[2518]//NextaddthesecondUTFforNameAndType.[2519]ul=newCONSTANT—Utf8—info("(Ljava/lang/string;)Z,r);[2520]cf.constant—pool[cf·constant—pool·length-3]=ul;[2521]//NextaddtheNameAndTypefortheprevioustwoUTFs.[2522]CONSTANT—NameAndType—infonl=newCONSTANT—NameAndType—info([2523]cf.constant—pool·length-4,cf.constant—pool·length-3);[2524]cf.constant—pool[cf·constant—pool·length-2]=nl;[2525]//NextaddtheMethodrefforthepreviousCLASSandNameAndType.[2526]CONSTANT—Methodref—infoml=newCONSTANT—Methodref—info{[2527]cf.constant—pool·length-5,cf.constant—pool·length-2);[2528]cf.constant—pool[cf·constant—pool·length-1]=ml;[2529]//Nowwiththatdone,addtheinstructionsintothecode,[2530]starting[2531]//withLDC.[2532]ca.code=newbyte[3];[2533]ca.code=(byte)19;[2534]ca.code[1]=(byte)(((cf.constant—pool·length-7)>>8)&87[2535]Oxff);[2536]ca.code[2]=(byte)((cf·constant—pool·length_7)&0xff);[2537]//NowAddtheINV0KESTATICinstruction.[2538]ca.code[1]=newbyte[3];[2539]ca.code[l]=(byte)184;[2540]ca.code[1][1]=(byte)(((cf.constant—pool·length-1)>>8)&[2541]Oxff);[2542]ca.code[1][2]=(byte)((cf·constant—pool·length-1)&0xff);[2543]//NextaddthelFEQinstruction.[2544]ca.code[2]=newbyte[3];[2545]ca.code[2]=(byte)153;[2546]ca.code[2][1]=(byte)((4>>8)&0xff);[2547]ca.code[2][2]=(byte)(4&0xff);[2548]//Finally,addtheRETURNinstruction.[2549]ca.code[3]=newbyte[1];[2550]ca.code[3]=(byte)177;[2551]//Lastly,incrementtheCODELENGTHandATTRIBUTELENGTHvalues.[2552]ca.code_length+=10;[2553]ca.attribute_length+=10;[2554]}[2555]}[2556]try{[2557]ByteArrayOutputStreamout=newByteArrayOutputStream();[2558]cf.serialize(out);[2559]byte[]b=out.toByteArray();[2560]returndefineClass(name,b,0,b.length);[2561]}catch(Exceptione){[2562]e.printStackTrace();[2563]thrownewClassNotFoundException(name);[2564]ι[2565]}[2566]}[2567]附件C[2568]Cl.用于單個(gè)機(jī)器的典型現(xiàn)有技術(shù)的終結(jié)化[2569]Methodfinalize()[2570]0getstatic#9〈Fieldjava.io.PrintStreamout>[2571]3ldc#24<String,/Deleted...">[2572]5invokevirtual#16〈Methodvoidprintln(javaa.lang.String)>88[2573]8returnC2.用于多個(gè)機(jī)器的優(yōu)選終結(jié)化Methodfinalize()0invokestatic#3〈MethodbooleanisLastReference()>3ifne76return7getstatie#9<Fieldjava.io.PrintStreamout>10ldc#24<String//Deleted...">12invokevirtual#16<Methodvoidprintln(java.lang.String)>15returnC3.用于多個(gè)機(jī)器的優(yōu)選終結(jié)化(可替換的)Methodfinalize()0aload_01invokestatic#3<MethodbooleanisLastReference(java.lang.Object))4ifne87return8getstatic#9<Fieldjava.io.PrintStreamout>11ldc#24<String//Deleted...">13invokevirtual#16<Methodvoidprintln(jaava.lang.String))附件C4importjava.lang.~k;publicclassexample{/**Finalizemethod.*/protectedvoidfinalize()throwsThrowable{/I"Deleted..."isprintedoutwhenthisobjectisgarbaged.System,out.println("Deleted...");}}附件C5importjava.lang.~k;importjava.util.*;importjava.net.*;importjava.io.*;publicclassFinalClient{/**Protocolspecificvalues.*/publicfinalstaticintCLOSE=_1;publicfinalstaticintNACK=0;publicfinalstaticintACK=1;publicfinalstaticintFINALIZE_0BJECT=10;89[2612]/**Finalservernetworkvalues.*/publicfinalstaticStringserverAddress=System.getProperty("FinalServer—network—address");publicfinalstaticintserverPort=Integer,parselnt(System.getProperty(“FinalServer—network—port"));/女女TableofglobalID/sforlocalobjects.(hashcode-to-globalIDmappings)*/publicfinalstaticHashtablehashCodeToGlobalID=newHashtable();/**Calledwhenaobjectisbeingfinalized.*/publicstaticbooleanisLastReference(0bjecto){//Firstofall,weneedtoresolvetheglobalIDforobject丨of·//TodothisweusethehashCodeToGlobalIDtable.intglobalID=((Integer)hashCodeToGlobalID.get(o)).intvalue();//Next,wewanttoconnecttotheFinalServer,whichwillinform//usofthefinalizationstatusofthisobject.Socketsocket=newSocket(serverAddress,serverPort);DataOutputStreamout=newDataOutputStream(socket.getOutputStream());DataInputStreamin=newDataInputStream(socket.getlnputStream());//0k,nowsendtheserializedrequesttotheFinalServer.out.writelnt(FINALIZE—OBJECT);out.writelnt(globalID);out.flush();//Nowwaitforthereply.intstatus=in.readlnt();//Thisisablockingcall.Sowe//willwaituntiltheremoteside//sendssomething.if(status==NACK){thrownewAssertionError(”Negativeacknowledgement.Requestfailed.”);}elseif(status!=ACK){throwmewAssertionError(〃Unknownacknowledgement:“+status+".Requestfailed.“);}//Next,readina32bitargumentwhichisthecountofthe//remainingfinalizationsintcount=in.readlnt();90[2649]//Ifthecountisequalto1,thenthisisthelastfinalization,//andhenceisLastReferenceshouldbetrue.//Ifhowever,thecountisgreaterthan1,thenthisisnotthe//lastfinalization,andthusisLastReferenceshouldbefalse.booleanisLastReference=(count==1true:false);//Closedowntheconnection.out.writelnt(CLOSE);out.flush();out.close();in.close();socket,close();//Makesuretoclosethesocket.//ReturnthevalueoftheisLastReferencevariable.returnisLastReference;}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}}附件C6importjava.lang.*;importjava.util.*;importjava.net.*;importjava.io.*;publicclassFinalServerimplementsRunnable{/**Protocolpecificvalues*/publicfinalstaticintCLOSE=_1;publicfinalstaticintNACK=O;publicfinalstaticintACK=1;publicfinalstaticintFINALIZE—OBJECT=10;/**FinalServernetwotkvalues.*/publicfinalstaticintserverPort=20001;/女女Tableoffinalizdtionrecords.女/publicfinalstaticHashtablefinalizations=newHashtable();/**Privateinput/outputobjects.*/privateSocketsocket=null;privateDataOutputStreamoutputStream;privateDataInputStreaminputStream;privateStringaddress;publicstaticvoidmain(String[]s)91[2688]operation}/necessarythrowsException{System,out.println("FinalServer_network_address="+InetAddress.getLocalHost().getHostAddress());System,out.println("FinalServer_network_port="+serverPort);//Createaserversockettoacceptincominginitialization//connections.ServerSocketserverSocket=newServerSocket(serverPort);while(!Thread,interrupted()){//Blockuntilanincominginitializationoperationconnection.Socketsocket=serverSocket.accept();//CreateanewinstanceofInitServertomanagethis//initializationoperationconnection.newThread(newFinalServer(socket)).start();-k*Constructor.InitializethisnewFinalServerinstancewithandvalues'resourcesforoperation.*publicFinalServer(Sockets){socket=s;try{outputStream=newDataOutputStream(s.qetOutputStream())inputStream=newDataInputStream(s.getlnputStream());address=s.getlnetAddress().getHostAddress();}catch(IoExceptione){thrownewAssertionError('Exception:"+e.toString())/~k-kMaincodebody.Decodeincomingfinalizationoperationrequestsexecuteaccordingly.*/publicvoidrun(){try{//Allcommandsareimplementedas32bitintegers.//Legalcommandsarelistedinthe"protocolspecific//fieldsabove.intcommand=inputStream.readlnt();92[2723]//ContinueprocessingcommandsuntilaCLOSEoperation.while(command!=CLOSE){if(comimnd==FINALIZE—OBJECT){//Thisisa//FmALIZE—OBJECT//operation.//ReadintheglobalIDoftheobjecttobefinalized.intglobalID=inputStream.readlnt();//Synchronizeonthefinalizationstableinordertoensure[2731]//thread-safety.synchronized(finalizations){//Locatethepreviousfinalizationsentryforthis//object,ifany.Integerentry=(Integer)finalizations·get(newlnteger(globalID));if(entry==null){thrownewAssertionError("Unknownobject.“);}elseif(entry.intValue()<1){thrownewAssertionError("Invalidcount.“);}elseif(entry.intValue()==1){//Countoflmeans//thisisthelast//reference,hence//removefromtable.finalizations.remove(newlnteger(globalID));//SendapositiveacknowledgementtoFinalClient,//togetherwith,thecountofremainingreferences-//whichinthiscaseis1.outputStream.writelnt(ACK);outputStream.writelnt(1);outputStream.flush();}else{//Thisisnotthelastremaining//reference,ascountisgreaterthan1.//Decrementcountby1.finalizations.put(newInteger(globalID),newlnteger(entry.intValue()-1));//SendapositiveacknowledgementtoFinalClient,//togetherwiththecountofremainingreferencesto//thisobject-whichinthiscaseofmustbevalue//"entry.intValue()".outputStream.writelnt(ACK);93[2762]outputStream.writelnt(entry.intValue());outputStream.flush();}}}else{//Unknowncommand.thrownewAssertionError(〃Unknowncommand.Operationfailed.〃);}//Readinthenextcommand.command=inputStream.readlnt();}}catch(Exceptione){thrownewAssertionError("Exception:“+e.toStringO);}finally{try{//Closingdown.Cleanupthisconnection.outputStream.flush();outputStream.close();inputStream.close();socket,close();}catch(Throwablet){t.printStackTraceO;}//Garbagethesereferences.outputStream=null;inputStream=null;socket=null;}}}附件C7FinalLoader.java該摘錄是FinalLoader的源代碼,其在加載應(yīng)用時(shí)對(duì)其進(jìn)行修改。importjava.lang.*;importjava.io.*;importjava.net.*;publicclassFinalLoaderextendsURLClassLoader{publicFinalLoader(URL[Juris){super(urls);94[2801]}protectedClassfindClass(Stringname)throwsClassNotFoundException{ClassFilecf=null;try{BufferedInputStreamin=newBufferedInputStream(findResource(name,replace(f.‘,'Γ).concat(".class")).openStreamO);cf=newClassFile(in);}catch(Exceptione){thrownewClassNotFoundException(e.toStringO);}for(inti=O;i<cf.methods—count;i++){//Findthefinalizemethod—infostruct.StringmethodName=cf.constant—pool[cf.methods[i].name_index].toStringO;if(!methodName.equals(/rfinalize'7)){continue;}//NowfindtheCode_attributeforthefinalizemethod.for(intj=O;j<cf.methods[i].attributes_count;j++){if(!(cf.methods[i].attributes[j]instanceofCode_attribute))continue;Code_attributeca=(Code_attribute)cf.methods[i].attributes[j];//First,shiftthecode[]downby‘instructions.byte[][]code2=newbyte[ca.code,length+4][];System,arraycopy(ca.code,O,code2,4,ca.code,length);ca.code=code2;//Thenenlargetheconstant—poolby6items.cp_info[]cpi=newcp_info[cf.constant—pool,length+6];System,arraycopy(cf.constant—pool,0,cpi,O,cf.constant—pool,length);cf.constant—pool=cpi;cf.constant—pool_count+=6;//NowaddtheUTFforclass.C0NSTANT_Utf8_infoul=newC0NSTANT_Utf8_info("FinalClient");cf.constant—pool[cf.constant—pool,length—6]=ul;[2836]info{NameAndType.starting[2861][2862]8)&Oxff);//NowaddtheCLASSforthepreviousUTF.CONSTANT_Class_infocl=newCONSTANT_Class_info(of.constant_pool.length-6);cf.constant_pool[cf.constant_pool.length-5]=cl;//NextaddthefirstUTFforNameAndType.ul=newC0NSTANT_Utf8_info("isLastReference");cf.constant_pool[cf.constant_pool.length-4]=ul;//NextaddthesecondUTFforNameAndType.ul=newC0NSTANT_Utf8_info("(Ljava/lang/Object;)Z");cf.constant_pool[cf.constant_pool.length-3]=ul;//NextaddtheNameAndTypefortheprevioustwoUTFs.CONSTANT_NameAndType_infonl=newC0NSTANT_NameAndType_cf.constant_pool.length-4,cf.constant_pool.length-3);cf.constant_pool[cf.constant_Pool.length-2]=nl;//NextaddtheMethodrefforthepreviousCLASSandC0NSTANT_Methodref_infoml=newC0NSTANT_Methodref_info{cf.constant_pool.length-5,cf.constant_pool.length-2);cf.constant_pool[cf.constant_pool.length-1]=ml;//Nowwiththatdone,addtheinstructionsintothecode,//withLDC.ca.code=newbyte[1];ca.code=(byte)42;//NowAddtheINVOKESTATICinstruction.ca.code[1]=newbyte[3];ca.code[l]=(byte)184;ca.code[1][1]=(byte)(((cf.constant_pool.length-1)>>ca.code[1][2]=(byte)((cf.constant_pool.length-1)&0xff);//NextaddtheIFNEinstruction.ca.code[2]=newbyte[3];ca.code[2]=(byte)154;ca.code[2][1]=(byte)((4>>8)&0xff);ca.code[2][2]=(byte)(4&0xff);//Finally,addtheRETURNinstruction.ca.code[3]=newbyte[1];[2872]ca.code[3]=(byte)177;//Lastly,incrementtheC0DE_LENGTHandATTRIBUTE_LENGTHvalues.ca.code_length+=8;ca.attribute—length+=8;}}try{ByteArrayOutputStreamout=newByteArrayOutputStream();cf.serialize(out);byte[]b=out.toByteArray();returndefineClass(name,b,0,b.length);}catch(Exceptione){e.printStackTrace();thrownewClassNotFoundException(name);}}}附件DlMethodvoidrun()Ogetstatic#2<Fieldjava.lang.0bjectL0CK>3dup4astore_l5monitorenter6getstatic#3<Fieldintcounter)9iconst_l10iadd11putstatic#3<Fieldintcounter)14aload_l15monitorexit16return附件D2Methodvoidrun()Ogetstatic#2<Fieldjava.lang,ObjectL0CK>3dup4astore_l5dnp6monitorenter7invokestatic#23<MethodvoidacquireLock(javaa.lang.Object))[2910]10getstatic#3〈Fieldintcounter)[2911]13iconSt—1[2912]14iadd[2913]15putstatic#3〈Fieldintcounter)[2914]18aload_l[2915]19dup[2916]20invokestatic#24〈MethodvoidreleaseLock(java.lang.Object)>[2917]23monitorexit[2918]24return[2919]附件D3[2920]importjava.lang.;[2921]pubIicclassexample{[2922]/**Sharedstaticfield.*/[2923]publicfinalstaticObjectLOCK=newObject();[2924]/女女Sharedstaticfield.女/[2925]publicstaticintcounter=0;[2926]/**Examplemethodusingsynchronization.Thismethodservesto[2927]illustratetheuseofsynchronizationtoimplementthread-safe[2928]modificationofasharedmemorylocationbypotentiallymultiple[2929]threads.*/[2930]publicvoidrun(){[2931]//Firstacquirethelock,otherwiseanymemorywriteswedowillbe[2932]//pronetorace-conditions.[2933]synchronized(LOCK){[2934]//Nowthatwehaveacqdiredthelbck,wecansafelymodifymemory}elseif(status!=ACK){thrownewAssertionError(〃Unknownacknowledgement:“+status+".Requestfailed.");}//Closedowntheconnection.out.writelnt(CLOSE);out.flush(};out.close();in.close();socket,close();//Makesuretoclosethesocket.//Thisisagoodacknowledgement,thuswecanreturnnowbecause//globallockisnowacquired.return;}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}/**Calledwhenanapplicationistoreleasealock.*/publicstaticvoidreleaseLock(Objecto){//Firstofall,weneedtoresolvetheglobalIDforobject'o'.//TodothisweusethehashCodeToGlobalIDtable.intglobalID=((Integer)hashCodeToGlobalID.get(o)).intValue();try{//Next,wewanttoconnecttotheLockServer,whichrecordsusas//theownerofthegloballockforobject'o'.Socketsocket=newSocket(serverAddress,serverPort);DataOutputStreamout=newDataOutputStream(socket.get0utputStream());DataInputStreamin=newDataInputStream(socket.getlnputStreamO);//0k,nowsendtheserializedrequesttothelockserver.out.writelnt(RELEASE_L0CK);out.writelnt(globalID);out.flush();//Nowwaitforthereply.intstatus=in.readlnt();//Thisisablockingcall.Sowe//willwaituntiltheremotesideHsendssomething.100[3020]if(status==NACK){thrownewAssertionError("Negativeacknowledgement.Requestfailed.");}elseif(status!=ACK){thrownewAssertionError("Unknownacknowledgement:"+status+".Requestfailed.");}//Closedowntheconnection.out.writelnt(CLOSE);out.flush();out.close();in.close();socket,close();//Makesuretoclosethesocket.//Thisisagoodacknowledgement,returnbecausegloballockis//nowreleased.return;}catch(IOExceptione){thrownewAssertionError("Exception:"+e.toString());}}}附件D5importjava.lang.~k;importjava.util.*;importjava.net.*;importjava.io.*;publicclassLockServerimplementsRunnable{/**Protocolspecificvalues*/publicfinalstaticintCLOSE=_1;publicfinalstaticintNACK=O;publicfinalstaticintACK=1;publicfinalstaticintACQUIRELOCK=10;publicfinalstaticintRELEASELOCK=20;/**LockServernetworkvalues.*/publicfinalstaticintserverPort=20001;/**Tableoflockrecords.*/publicfinalstaticHashtablelocks=newHashtable();/-k-kLinkedlistofwaitingLockManagerobjects.~k/publicLockServernext=null;101[3059[3060[3061[3062[3063[3064[3065[3066[3067[3068[3069/**AddressofremoteLockClient.*/publicfinalStringaddress;/**Privateinput/outputobjects.*/privateSocketsocket=null;privateDataOutputStreamoutputStream;privateDataInputStreaminputStream;publicstaticvoidmain(String[]s)throwsException{System,out.println("LockServer_network_address=+InetAddress.getLocalHost().getHostAddress());System.out.println(LockServer_network_port+serverPort)execute-k//Createaserversockettoacceptincominglockoperation//connectiohs.ServerSocketserverSocket=newServerSocket(serverPort);while(!Thread,interrupted()){//Blockuntilanincominglockoperationconnection.Socketsocket=serverSocket.accept();//CreateanewinstanceofLockServertomanaqethislock//operationconnection.newThread(newLockServer(socket)).start();*Constructor.InitialisethisnewLockServerinstancewithresourcesforoperation.*/publicLockServer(Sockets){socket=s;try{outputStream=newDataOutputStream(s.getOutputStream())inputStream=newDataInputStream(s.getlnputStream());address=s.getlnetAddress().getHostAddress();}catch(IOExceptione){thrownewAssertionError("Exception:"+e.toString());~k-kMaincodebody.Decodeincominglockoperationrequestsandaccordingly.*102[3095]values‘publicvoidrun(){try{//Allcommandsareimplementedas32bitintegers.//Legalcommnandsarelistedinthe"protocolspecific//fieldsabove,intcommand=inputStream.readlnt();//ContinueprocessingcommandsuntilaCLOSEoperation,while(command!=CLOSE){if(command==ACQUIRELOCK){,Thisisan/ACQUIRE_L0CK//operation.//ReadintheglobalIDoftheobjecttobelocked,intglobalID=inputStream.readlnt();//Synchronizeonthelockstableinordertoensurethread-//safety.synchronized(locks){//Checkforanexistingownerofthislock.LockServerlock=(LockServer)locks,get(newlnteger(globalID));if(lock==null){//No-onepresentlyownsthislock,//soacquireit.locks,put(newlnteger(globalID),this);acquireLock();//Signaltotheclientthe//successfulacquisitionofthis//lock.}else{//Alreadyowned.Appendourselves//toendofqueue.//Searchfortheendofthequeue.(Implementedas//linked-list)while(lock,next!=null){lock=lock,next;lock,next=this;//Appendthislockrequestatend.}elseif(command==RELEASE_L0CK){//Thisisa//RELEASE_L0CK//operation.103[3133]//ReadintheglobalIDoftheobjecttobelocked.intglobalID=inputStream.readlnt();//Synchronizeonthelockstableinordertoensurethread—//safety.synchronized(locks){//Checktomakesurewearetheownerofthislock.LockServerlock=(LockServer)locks,get{newInteger(globalID));if(lock==null){thrownewAssertionError(〃Unlocked.Releasefailed.〃);}elseif(lock,address!=this,address){thrownewAssertionError("Tryingtoreleasealock"+"whichthisclientdoesn/town.Release“+"failed.“);}lock=lock,next;lock.acquireLock();//Signaltotheclientthe//successfulacquisitionofthis//lock.//Shiftthelinkedlistofpendingacquisitionsforward//byone.locks,put(newlnteger(globalID),lock);//Clearstalereference.next=null;}releaseLock();//Signaltotheclientthesuccessful//releaseofthislock.}else{//Unknowncommand.thrownewAssertionError(〃Unknowncommand.Operationfailed.〃);}//Readinthenextcommand.command=inputStream.readlnt();}}catch(Exceptione){thrownewAssertionError("Exception:“+e.toStringO);}finally{try{//Closingdown.Cleanupthisconnection.[3172]outputStream.flush();outputStream.close();inputStream.close();socket,close();}catch(Throwablet)(t.printStackTrace();}HGarbagethesereferences.outputStream=null;inputStream=null;socket=null;}}I±±SendapositiveacknowledgementofanACQUIRE—LOCKoperation.女/publicvoidacquireLock()throwsIOException{outputStream.writelnt(ACK);outputStream.flush();}/**SendapositiveacknowledgementofaRELEASE_L0CKoperation.女/publicvoidreleaseLock()throwsIOException{outputStream.writelnt(ACK);outputStream.flush();}}附件D6LockLoader.java該摘錄是LockLoader的源代碼,其在加載應(yīng)用時(shí)對(duì)其進(jìn)行修改。importjava.lang.*;importjava.io.*;importjava.net.*;publicclassLockLoaderextendsURLVlassLoader{publicLockLoader(URL[]urIs){super(urls);}protectedClassfindClass(Stringname)throwsClassNotFoundException{ClassFilecf=null;105[3209]try{[3210]BufferedInputStreamin=[3211]newBufferedInputStream(findResource(name,replace('.',[3212]'/').concat(".class")).openStream());[3213]cf=newClassFile(in);[3214]}catch(Exceptione)(thrownewClassNotFoundException(e.tostringO);}[3215]//Class-widepointerstotheenterindexandexitindex.[3216]intenterindex=-1;[3217]intexitindex=-1;[3218]for(inti=0;i<cf.methodscount;i++){[3219]for(intj=0;j<cf.methods[i].attributes_count;j++){[3220]if(!(cf.methods[i].attributes[j]instanceofCode_attribute))[3221]continue;[3222]Code_attributeca=(Code_attribute)cf.methods[i].attributes[j][3223]booleanchanged=false;[3224]for(intz=0;z<ca.code,length;z++){[3225]if((ca.code[z]&0xff)==194){//Opcodefora[3226]//M0NIT0RENTER[3227]//instruction.[3228]changed=true;[3229]//Next,realignthecodearray,makingroomforthe[3230]Ilinsertions.[3231]byte[][]code2=newbyte[ca.code,length+2][];[3232]System,arraycopy(ca.code,0,code2,0,z);[3233]code2[z+1]=ca.code[z];[3234]System,arraycopy(ca.code,z+1,code2,z+3,[3235]ca.code,length-(z+1));[3236]ca.code=code2;[3237]//Next,inserttheDUPinstruction.[3238]ca.code[z]=newbyte[1];[3239]ca.code[ζ]=(byte)89;[3240]//Finally,inserttheINV0KESTATICinstruction.[3241]if(enterindex==_1){[3242]//Thisisthefirsttimethisclassisencourtering[3243]the[3244]//acquirelockinstruction,sohavetoaddittothe//constantpool.cp_info[]cpi=newcp_info[cf.constant_pool.length+6];System,arraycopy(cf.constant_pool,0,cpi,0,cf.constant_pool.length);cf.constant_pool=cpi;cf.constant_pool_count+=6;C0NSTANT_Utf8_infoul=newC0NSTANT_Utf8_info("LockClient");cf.constant_pool[cf.constant_pool.length-6]=ul;C0NSTANT_Class_infocl=newC0NSTANT_Class_info{cf.constant_pool_count_6);cf.constant_pool[cf.constant_pool.length-5]=cl;ul=newC0NSTANT_Utf8_info("acquireLock");cf.constant_pool[cf.constant_pool.length-4]=ul;ul=newC0NSTANT_Utf8_info("(Ljava/lang/Object;)V");cf.constant_pool[cf.constant_pool.length-3]=ul;CONSTANT_NameAndType_infonl=newCONSTANT_NameAndType_info{cf.constant_pool.length-4,cf.constant_pool.Iength-3);cf.constant_pool[cf.constant_pool.length-2]=nl;C0NSTANT_Methodref_infoml=newC0NSTANT_Methodref_info(cf.constant_pool.length-5,cf.constant_pool.Iength-2);cf.constant_pool[cf.constant_pool.length-1]=ml;enterindex=cf.constant_pool.length-1;}107[3273]ca.code[z+2]=newbyte[3];ca.code[z+2]=(byte)184;ca.code[z+2][1]=(byte)((enterindex>>8)&0xff);ca.code[z+2][2]=(byte)(enterindex&Oxff);//Andlastly,increasetheCODE_LENGTHandATTRIBUTE_LENGTH//values.ca.code_length+=4;ca.attribute—length+=4;ζ+=1;}elseif((ca.code[z]&Oxff)==195){//Opcodefora//M0NIT0REXITIlinstruction.changed=true;//Next,realignthecodearray,makingroomforthe//insertions.byte口[]code2=newbyte[ca.code,length+2][];System,arraycopy(ca.code,0,code2,0,z);code2[z+l]=ca.code[z];System,arraycopy(ca.code,z+1,code2,z+3,ca.code,length-(z+1));ca.code=code2;//Next,inserttheDUPinstruction.ca.code[z]=newbyte[l];ca.code[ζ]=(byte)89;//Finally,inserttheINV0KESTATICinstruction.if(exitindex==_1){//Thisisthefirsttimethisclassisencourteringthe//acquirelockinstruction,sohavetoaddittothe//constantpool.cp_info[]cpi=newcp_info[cf.constant_pool.length+6];System,arraycopy(cf.constant_pool,0,cpi,0,cf.constant_pool.length);cf.constant_pool=cpi;cf.constant_pool_count+=6;[3309]CONSTANTUtf8_infoul=newC0NSTANT_Utf8_info("LockClient“);cf.constant_pool[cf.constant_pool.length-6]=ul;CONSTANT_Class_infocl=newCONSTANT_Class_info(cf.constant_pool_count_6);cf.constant_pool[cf.constant_pool.length-5]=cl;ul=newC0NSTANT_Utf8_info("releaseLock");cf.constant_pool[cf.constant_pool.length-4]=ul;ul=newC0NSTANT_Utf8_info("(Ljava/lang/Object;)V");cf.constant_pool[cf.constant_pool.length-3]=ul;CONSTANT_NameAndType_infonl=newCONSTANT_NameAndType_info{cf.constant_pool.length-4,cf.constant_pool.Iength-3);cf.constant_pool[cf.constant_pool.length-2]=nl;CONSTANT_Methodref_infoml=newCONSTANT_Methodref_info(cf.constant_pool.length-5,cf.constant_pool.Iength-2);cf.constant_pool[cf.constant_pool.length-1]=ml;exitindex=cf.constant_pool.length-1;}ca.code[z+2]=newbyte[3];ca.code[z+2]=(byte)184;ca.code[z+2][1]=(byte)((exitindex>>8)&0xff);ca.code[z+2][2]=(byte)(exitindex&Oxff);//Andlastly,increasetheCODE_LENGTHandATTRIBUTE_LENGTH//values.ca.code_length+=4;109[3339]ca.attribute_length+=4;ζ+=1;7Ifwechangedthismethod,thenincreasethestacksizebyone.if(changed){ca.max_stack++;7Justtomakesure.try{ByteArrayOutputStreamout=newByteArrayOutputStream();cf.serialize(out);byte[]b=out.toByteArray();returndefineClass(name,b,0,b.length);}catch(Exceptione){thrownewClassNotFoundException(name);權(quán)利要求一種多計(jì)算機(jī)系統(tǒng),所述多計(jì)算機(jī)系統(tǒng)具有至少一個(gè)應(yīng)用程序,所述應(yīng)用程序在通過通信網(wǎng)絡(luò)互連的多個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行,其中所述應(yīng)用程序的不同部分基本上同時(shí)在所述多個(gè)計(jì)算機(jī)中不同的計(jì)算機(jī)上執(zhí)行,其中對(duì)于每個(gè)所述部分,創(chuàng)建同樣多個(gè)基本上相同的對(duì)象,每個(gè)所述對(duì)象在對(duì)應(yīng)的計(jì)算機(jī)中,且其中每個(gè)所述計(jì)算機(jī)的所有讀請(qǐng)求僅從讀在請(qǐng)求計(jì)算機(jī)中創(chuàng)建的對(duì)象來滿足。2.如權(quán)利要求1所述的系統(tǒng),其中所述多個(gè)基本上相同的對(duì)象的每個(gè)具有基本上相同的名稱。3.如權(quán)利要求2所述的系統(tǒng),其中所述的相同命名對(duì)象的每個(gè)的初始內(nèi)容是基本上相同的。4.如權(quán)利要求2或3所述的系統(tǒng),其中當(dāng)各個(gè)所述多個(gè)計(jì)算機(jī)都不再需要引用各個(gè)相同對(duì)象的組的其對(duì)應(yīng)對(duì)象時(shí),全體刪除所述相同對(duì)象的組。5.如權(quán)利要求4所述的系統(tǒng),其中每個(gè)所述計(jì)算機(jī)包括分布式運(yùn)行時(shí)間裝置,其中每個(gè)所述計(jì)算機(jī)的分布式運(yùn)行時(shí)間裝置能夠與所有其他計(jì)算機(jī)通信,由此如果運(yùn)行在所述計(jì)算機(jī)之一上的所述應(yīng)用程序的一部分不再需要引用該計(jì)算機(jī)中的對(duì)象,則將不再引用的對(duì)象的標(biāo)識(shí)由所述的一個(gè)計(jì)算機(jī)的分布式運(yùn)行時(shí)間裝置傳送給可由所有其他計(jì)算機(jī)訪問的共享表。6.如權(quán)利要求5所述的系統(tǒng),其中通過插入終結(jié)化例程,在加載之前、期間或之后,對(duì)每個(gè)所述應(yīng)用程序進(jìn)行修改,以對(duì)其中所述應(yīng)用程序不再需要引用對(duì)象的每個(gè)實(shí)例進(jìn)行修改。7.如權(quán)利要求6所述的系統(tǒng),其中所述的所插入的終結(jié)化例程修改預(yù)先存在的終結(jié)化例程,以便在所有計(jì)算機(jī)不再需要引用其對(duì)應(yīng)對(duì)象時(shí)使所述預(yù)先存在的終結(jié)化例程能夠執(zhí)行,并在至少一個(gè)計(jì)算機(jī)確實(shí)需要引用對(duì)應(yīng)對(duì)象時(shí),禁止預(yù)先存在的終結(jié)化例程。8.如權(quán)利要求2-4中任意一項(xiàng)所述的系統(tǒng),包括可應(yīng)用于所有所述計(jì)算機(jī)的鎖定裝置,其中想要利用其中所命名的對(duì)象的任何計(jì)算機(jī)從所述鎖定裝置獲取授權(quán)鎖定,所述授權(quán)鎖定允許所述利用,并防止所有其他計(jì)算機(jī)利用其對(duì)應(yīng)的命名對(duì)象,直到所述授權(quán)鎖定被放棄9.如權(quán)利要求8所述的系統(tǒng),其中所述鎖定裝置包括獲取鎖定例程和釋放鎖定例程,且兩個(gè)所述例程都包括于對(duì)運(yùn)行在所有所述計(jì)算機(jī)上的所述應(yīng)用程序所作的修改中。10.如權(quán)利要求9所述的系統(tǒng),其中所述鎖定裝置進(jìn)一步包括共享表,該共享表列出任何所述計(jì)算機(jī)所使用的所述命名對(duì)象、每個(gè)所述對(duì)象的鎖定狀態(tài)和任何未決的鎖定獲取的隊(duì)列。11.如權(quán)利要求10所述的系統(tǒng),其中所述鎖定裝置位于不運(yùn)行所述應(yīng)用程序且連接至所述通信網(wǎng)絡(luò)的附加計(jì)算機(jī)內(nèi)。12.如權(quán)利要求11所述的系統(tǒng),其中通過插入所述獲取鎖定例程和所述釋放鎖定例程,在加載之前、期間或之后,對(duì)每個(gè)所述應(yīng)用程序進(jìn)行修改,以對(duì)其中所述應(yīng)用程序分別獲取和釋放對(duì)對(duì)象的鎖定的每個(gè)實(shí)例進(jìn)行修改。13.如權(quán)利要求1-12中任意一項(xiàng)所述的系統(tǒng),其中每個(gè)所述計(jì)算機(jī)包括分布式更新裝置,其中每個(gè)所述計(jì)算機(jī)的分布式更新裝置能夠與所有其他計(jì)算機(jī)通信,以使得如果運(yùn)行在所述計(jì)算機(jī)之一上的所述應(yīng)用程序的一部分改變?cè)撚?jì)算機(jī)中對(duì)象的內(nèi)容,則將所述對(duì)象的內(nèi)容的改變通過所述一個(gè)計(jì)算機(jī)的分布式更新裝置傳播到所有其他計(jì)算機(jī),以改變每個(gè)所述其他計(jì)算機(jī)中的對(duì)應(yīng)對(duì)象的內(nèi)容。14.如權(quán)利要求13所述的系統(tǒng),其中所有所述分布式更新裝置以明顯小于本地存儲(chǔ)器讀速率的數(shù)據(jù)傳送速率經(jīng)由所述通信鏈路來通信。15.如權(quán)利要求1-14中任意一項(xiàng)所述的系統(tǒng),其中通過插入更新傳播例程,在加載之前、期間或之后,對(duì)每個(gè)所述應(yīng)用程序進(jìn)行修改,以對(duì)所述應(yīng)用程序在其處寫入存儲(chǔ)器的每個(gè)實(shí)例進(jìn)行修改,所述更新傳播例程將一個(gè)計(jì)算機(jī)的每個(gè)存儲(chǔ)器寫傳播到所有所述其他計(jì)算機(jī)。16.如權(quán)利要求1-15中任意一項(xiàng)所述的系統(tǒng),其中通過插入初始化例程,在加載之前、期間或之后,對(duì)每個(gè)所述應(yīng)用程序進(jìn)行修改,以對(duì)所述應(yīng)用程序在其處創(chuàng)建對(duì)象的每個(gè)實(shí)例進(jìn)行修改,所述初始化例程將一個(gè)計(jì)算機(jī)新創(chuàng)建的每個(gè)對(duì)象都傳播到所有所述其他計(jì)算機(jī)。17.如權(quán)利要求16所述的系統(tǒng),其中所述的所插入的初始化例程修改預(yù)先存在的初始化例程,以便使所述預(yù)先存在的初始化例程能夠在創(chuàng)建了所述同樣多個(gè)對(duì)象的第一個(gè)對(duì)象時(shí)執(zhí)行,并在創(chuàng)建了所述的同樣多個(gè)對(duì)象的所有后續(xù)對(duì)象時(shí),禁止所述預(yù)先存在的初始化例程。18.如權(quán)利要求17所述的系統(tǒng),其中所述應(yīng)用程序是根據(jù)從以下構(gòu)成的過程組中所選的過程來修改的加載時(shí)的重新編譯、加載前的預(yù)編譯、加載前的編譯、正好適時(shí)的編譯以及加載后且在應(yīng)用程序的相關(guān)部分執(zhí)行前的重新編譯。19.如權(quán)利要求18所述的系統(tǒng),其中所述被修改的應(yīng)用程序根據(jù)從以下構(gòu)成的組中所選的過程而被傳送到所有所述計(jì)算機(jī)主/從傳送、分支傳送和級(jí)聯(lián)傳送。20.如權(quán)利要求1-19中任意一項(xiàng)所述的系統(tǒng),其中分配給所述應(yīng)用程序或每個(gè)所述應(yīng)用程序的本地存儲(chǔ)器容量是基本上相同的,并且對(duì)所述應(yīng)用程序或每個(gè)所述應(yīng)用程序可用的總存儲(chǔ)器容量是所述的所分配的存儲(chǔ)器容量。21.如權(quán)利要求1-20中任意一項(xiàng)所述的系統(tǒng),其中所述計(jì)算機(jī)的至少一些是由不同制造商來制造的和/或具有不同的操作系統(tǒng)。22.—種在多個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行至少一個(gè)應(yīng)用程序的方法,所述計(jì)算機(jī)借助于通信網(wǎng)絡(luò)來互連,所述方法包括以下步驟(i)在所述計(jì)算機(jī)中的不同計(jì)算機(jī)上執(zhí)行所述應(yīng)用程序的不同部分,以及對(duì)于每個(gè)所述部分,創(chuàng)建同樣多個(gè)基本上相同的對(duì)象,所述對(duì)象每個(gè)在對(duì)應(yīng)的計(jì)算機(jī)中;以及()通過僅從讀在請(qǐng)求計(jì)算機(jī)中創(chuàng)建的對(duì)象來滿足每個(gè)所述計(jì)算機(jī)的所有讀請(qǐng)求。23.如權(quán)利要求22所述的方法,進(jìn)一步包括以下步驟(iii)以基本上相同的名稱對(duì)每個(gè)所述多個(gè)基本上相同的對(duì)象命名。24.如權(quán)利要求22或23中所述的方法,進(jìn)一步包括以下步驟(iv)如果運(yùn)行在所述計(jì)算機(jī)之一上的所述應(yīng)用程序的一部分改變?cè)撚?jì)算機(jī)中對(duì)象的內(nèi)容,則將所述對(duì)象的內(nèi)容的改變經(jīng)由所述通信網(wǎng)絡(luò)傳播到所有其他計(jì)算機(jī),以改變每個(gè)所述其他計(jì)算機(jī)中的對(duì)應(yīng)對(duì)象的內(nèi)容。25.如權(quán)利要求24中所述的方法,進(jìn)一步包括以下步驟(ν)通過插入更新傳播例程,在加載之前、期間或之后,對(duì)所述應(yīng)用程序進(jìn)行修改,以對(duì)所述應(yīng)用程序在其處寫入存儲(chǔ)器的每個(gè)實(shí)例進(jìn)行修改,所述更新傳播例程將一個(gè)計(jì)算機(jī)的每個(gè)存儲(chǔ)器寫傳播到所有所述其他計(jì)算機(jī)。26.如權(quán)利要求25所述的方法,進(jìn)一步包括以下步驟(vi)利用從以下構(gòu)成的過程組中所選的過程來修改所述應(yīng)用程序加載時(shí)的重新編譯、加載前的預(yù)編譯、加載前的編譯、正好適時(shí)的編譯以及在加載之后且在應(yīng)用程序的相關(guān)部分執(zhí)行之前的重新編譯。27.如權(quán)利要求26所述的方法,進(jìn)一步包括以下步驟(vii)利用從以下構(gòu)成的組中所選的過程將所述的修改后的應(yīng)用程序傳送到所有所述計(jì)算機(jī)主/從傳送、分支傳送和級(jí)聯(lián)傳送。28.如權(quán)利要求25-27中任意一項(xiàng)所述的方法,進(jìn)一步包括下列步驟(viii)以明顯小于本地存儲(chǔ)器讀速率的數(shù)據(jù)傳送速率來傳送構(gòu)成更新數(shù)據(jù)傳輸?shù)乃霰镜卮鎯?chǔ)器寫。29.如權(quán)利要求23-28中任意一項(xiàng)所述的方法,進(jìn)一步包括下列步驟(ix)將所述的相同命名對(duì)象的每個(gè)的初始內(nèi)容創(chuàng)建為基本上相同。30.如權(quán)利要求29所述的方法,進(jìn)一步包括以下步驟(χ)如果在所述計(jì)算機(jī)之一上運(yùn)行的所述應(yīng)用程序的部分在該計(jì)算機(jī)中創(chuàng)建對(duì)象,那么所創(chuàng)建的對(duì)象經(jīng)由所述通信網(wǎng)絡(luò)被傳播到所有其他計(jì)算機(jī)。31.如權(quán)利要求30所述的方法,進(jìn)一步包括以下步驟(xi)通過插入初始化例程,在加載之前、期間或之后,對(duì)所述應(yīng)用程序進(jìn)行修改,以對(duì)所述應(yīng)用程序在其處創(chuàng)建對(duì)象的每個(gè)實(shí)例進(jìn)行修改,所述初始化例程將一個(gè)計(jì)算機(jī)創(chuàng)建的每個(gè)對(duì)象傳播到所有所述其他計(jì)算機(jī)。32.如權(quán)利要求31所述的方法,進(jìn)一步包括以下步驟(xii)利用從以下所構(gòu)成的過程的組中所選的過程,對(duì)所述應(yīng)用程序進(jìn)行修改加載時(shí)的重新編譯、加載之前的預(yù)編譯、加載之前的編譯、正好適時(shí)的編譯以及在加載之后且在應(yīng)用程序的相關(guān)部分執(zhí)行之前的重新編譯。33.如權(quán)利要求32所述的方法,進(jìn)一步包括以下步驟(xiii)利用從以下構(gòu)成的組中所選的過程,將所修改的應(yīng)用程序傳送到所有所述計(jì)算機(jī)主/從傳送、分支傳送和級(jí)聯(lián)傳送。34.如權(quán)利要求22-33中任意一項(xiàng)所述的方法,進(jìn)一步包括下列步驟(xiv)當(dāng)所有所述多個(gè)計(jì)算機(jī)均不再需要引用其對(duì)應(yīng)對(duì)象時(shí),將所有所述的相同對(duì)象全體刪除。35.如權(quán)利要求34所述的方法,進(jìn)一步包括以下步驟(xv)為每個(gè)所述計(jì)算機(jī)提供分布式運(yùn)行時(shí)間裝置,以經(jīng)由所述通信網(wǎng)絡(luò)在所述多個(gè)計(jì)算機(jī)之間進(jìn)行通信。36.如權(quán)利要求35所述的方法,進(jìn)一步包括以下步驟(xvi)提供可由每個(gè)所述分布式運(yùn)行時(shí)間裝置來訪問的共享表,其中存儲(chǔ)了不再需要訪問對(duì)象的任何計(jì)算機(jī)的標(biāo)識(shí)連同該對(duì)象的標(biāo)識(shí)。37.如權(quán)利要求36所述的方法,進(jìn)一步包括以下步驟(xvii)將計(jì)數(shù)器裝置與所述共享表關(guān)聯(lián),所述計(jì)數(shù)器裝置存儲(chǔ)對(duì)不再需要訪問所述對(duì)象的所述計(jì)算機(jī)數(shù)量的計(jì)數(shù)。38.如權(quán)利要求37所述的方法,進(jìn)一步包括以下步驟(xviii)提供附加的計(jì)算機(jī),所述共享程序不在所述附加的計(jì)算機(jī)上運(yùn)行,且所述附加的計(jì)算機(jī)容納所述共享表和計(jì)數(shù)器,所述的附加的計(jì)算機(jī)連接至所述通信網(wǎng)絡(luò)。39.如權(quán)利要求22-34中任意一項(xiàng)所述的方法,進(jìn)一步包括下列步驟(xviv)要求想要利用其中的命名對(duì)象的任何所述計(jì)算機(jī)獲取授權(quán)鎖定,所述授權(quán)鎖定允許所述利用,且其防止所有其他計(jì)算機(jī)來利用其對(duì)應(yīng)的命名對(duì)象,直到所述授權(quán)鎖定被放棄。40.如權(quán)利要求39所述的方法,進(jìn)一步包括以下步驟(xx)為每個(gè)所述計(jì)算機(jī)提供分布式運(yùn)行時(shí)間裝置,以經(jīng)由所述通信網(wǎng)絡(luò)在所述多個(gè)計(jì)算機(jī)之間進(jìn)行通信。41.如權(quán)利要求40所述的方法,進(jìn)一步包括以下步驟(xxi)提供可由每個(gè)所述分布式運(yùn)行時(shí)間裝置來訪問的共享表,其中存儲(chǔ)了當(dāng)前需要訪問對(duì)象的任何計(jì)算機(jī)的標(biāo)識(shí)連同該對(duì)象的標(biāo)識(shí)。42.如權(quán)利要求41所述的方法,進(jìn)一步包括以下步驟(xxii)將計(jì)數(shù)器裝置與所述共享表關(guān)聯(lián),所述計(jì)數(shù)器裝置存儲(chǔ)對(duì)尋求訪問所述對(duì)象的所述計(jì)算機(jī)數(shù)量的計(jì)數(shù)。43.如權(quán)利要求42所述的方法,進(jìn)一步包括以下步驟(xxiii)提供附加的計(jì)算機(jī),所述的共享程序不在所述附加的計(jì)算機(jī)上運(yùn)行,且所述附加的計(jì)算機(jī)容納所述共享表和計(jì)數(shù)器,所述的附加的計(jì)算機(jī)連接至所述通信網(wǎng)絡(luò)。44.一種單個(gè)計(jì)算機(jī),被布置為與至少一個(gè)其他同樣的計(jì)算機(jī)合作以形成權(quán)利要求1至21中任意一項(xiàng)所述的多計(jì)算機(jī)系統(tǒng)。全文摘要本發(fā)明公開了一種修改的計(jì)算機(jī)架構(gòu),其使得應(yīng)用程序(50)能夠在多個(gè)計(jì)算機(jī)(M1、...Mn)上同時(shí)運(yùn)行。每個(gè)計(jì)算機(jī)處的共享存儲(chǔ)器被以修改和/或覆寫來更新,以便使所有存儲(chǔ)器讀請(qǐng)求在本地得到滿足。在初始程序加載(75)期間,或相似過程期間,識(shí)別導(dǎo)致存儲(chǔ)器被重寫或操縱的指令(92)。此外,公開了JAVA語言類和對(duì)象的初始化(162,163),這樣所有計(jì)算機(jī)的所有存儲(chǔ)器位置以相同的方式被初始化。還公開了JAVA語言類和對(duì)象的終結(jié)化(162,163),這樣僅當(dāng)不再需要所有機(jī)器上的最后的類或?qū)ο髸r(shí),才會(huì)發(fā)生終結(jié)化。文檔編號(hào)G06F15/16GK101908001SQ201010247309公開日2010年12月8日申請(qǐng)日期2005年4月22日優(yōu)先權(quán)日2004年4月22日發(fā)明者約翰·馬修·霍爾特申請(qǐng)人:瓦拉泰克有限公司