


版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第2 分布式計算的Java模型我們可能都曾見過類似的錯誤信息:“NFSServernotresponding(NFS服務(wù)器無響應(yīng)),“unabletolocatetheserver(不能定位服務(wù)器),“pleasechecktheservernameandtry(請檢查服務(wù)器名稱后重試“noroutetohost(無法路由主機hostunreachable(主機不可達)等等,我們的桌面計算機原本就很脆弱,自從引入了網(wǎng)絡(luò),系統(tǒng)就更容易出現(xiàn)各類故障了。系統(tǒng)的脆弱有很多外觀上的原因。顯然,在網(wǎng)絡(luò)系統(tǒng)中有一些新問題會引起系統(tǒng)故障,一個關(guān)鍵路由器的故障是導(dǎo)致網(wǎng)絡(luò)應(yīng)用的常見原因,但對本地系統(tǒng)就不會有影響。所謂本地系統(tǒng),是指在獨立的一臺機器上運行,只有一個地址空間的應(yīng)用程序。當(dāng)然還有更的原因使得建立分布式網(wǎng)絡(luò)系統(tǒng)比建立獨立系統(tǒng)更加。事實上,這些原因也正解釋了為什么我們不能拋開網(wǎng)絡(luò),使系統(tǒng)看起來和本地系樣:使用同樣的編程模型,代碼可運行。本章將網(wǎng)絡(luò)系統(tǒng)和分布式系統(tǒng),并把二者區(qū)別開來。現(xiàn)在的很多,尤其是在eb出現(xiàn)之后,都是基于網(wǎng)絡(luò)的,而Jini代表了一種更復(fù)雜的模式:一種真正動態(tài)的分布式系統(tǒng)。下面看一下兩類的不同之處,分析一下為什么分布式系統(tǒng)編程的基本架構(gòu)還有些棘手的問題需要解決。建立在Java基礎(chǔ)上的Jini為分布式系統(tǒng)的問題提供了一些很好的思路,我們將分析一下這種基于Java的方案與以前的方法有何不同。為什么難以創(chuàng)建健壯的網(wǎng)絡(luò)呢?我們先看一下原來是用了哪些方法來解決網(wǎng)絡(luò)編程中的問題,而這些方法又存在什么缺陷?;蛟S能找到些答案。傳統(tǒng)網(wǎng)絡(luò)系網(wǎng)絡(luò)系統(tǒng)編程的歷史很多都是試圖隱藏網(wǎng)絡(luò)的存在。研究一下“經(jīng)典”網(wǎng)絡(luò)系統(tǒng)的架構(gòu),可以看到兩個共同點,第一,它們都提供把數(shù)據(jù)轉(zhuǎn)移到計算之處的方式;第二,它們都對處理數(shù)據(jù)的方式進行了明確的規(guī)定,這些方式來自一個可選擇的約束集合。因為不可能使完成某個指定操作所需的代碼在網(wǎng)絡(luò)中隨處可用,所以把數(shù)據(jù)轉(zhuǎn)移到計算發(fā)生的位置是必需的,實際上因為程序需要在不同的機器上編譯和安裝,程序可到處運行的設(shè)想很不容易實現(xiàn)。從這個角度看,轉(zhuǎn)移數(shù)據(jù)要比轉(zhuǎn)移代碼容易得多,但轉(zhuǎn)移數(shù)據(jù)也有很多問題,如不同的字節(jié)順序、不同的浮點格式、不同的字長等等。XDR(ExternalDataRepresentation,外部數(shù)據(jù)表示,Sun公司為支持可移植性使用的一種數(shù)據(jù)打包協(xié)議,從80年代中期開始使用)等數(shù)據(jù)表示工具通過隱藏各機器間不同的數(shù)據(jù)格式,使得各種CPU識別自己所接收的數(shù)據(jù),從而“隱藏”了網(wǎng)絡(luò)的存在。這些工具通過標(biāo)準(zhǔn)化一種可移植的特定線路格式,使數(shù)據(jù)獨立于各種機器自己的字節(jié)順序、字長等,從而支持數(shù)據(jù)在網(wǎng)絡(luò)中傳輸,無錯誤到達到需要的地方。當(dāng)數(shù)據(jù)到達目的地后,常用過程調(diào)用(RPC)或?qū)ο笙到y(tǒng)的方法進行處理。遠程過程調(diào)用系統(tǒng)試圖使對另一臺機器上的過程進行調(diào)用看起來像是對本地同一地址空間中過程進行調(diào)用;對象系統(tǒng)如 和 把編程的級別從過程調(diào)用抬高到對象的調(diào)用,但本質(zhì)上是模仿本地調(diào)用的方式。在過去20年中,對象系統(tǒng)與過程調(diào)用技術(shù)沒有本質(zhì)的區(qū)。當(dāng)然這些隱藏網(wǎng)絡(luò)的努力是基于一個重要的原因:程序員最初只理解基本的本地編程技術(shù),他們知道如何構(gòu)造可靠的獨立系統(tǒng),而如果增加一些引入了網(wǎng)絡(luò)的特殊編程模型,他們就需要花費的時間和精力學(xué)習(xí)新的模型。網(wǎng)絡(luò)并不透不幸的是,這種簡化有些過份,這些系統(tǒng)基于一種隱含的假設(shè)—在兩個程序之間引入網(wǎng)絡(luò),并不會影響它們的正確,只會影響效率。事實上,在傳統(tǒng)的網(wǎng)絡(luò)系統(tǒng)中確實需要隱藏特定對象的位置,就像在面象系統(tǒng)中把過程的實現(xiàn)隱藏而只提供接口;程序在網(wǎng)絡(luò)出現(xiàn)故障或性能過低的情況下如何工作,應(yīng)當(dāng)是其實現(xiàn)的另一方面,而不是接口或者它與系統(tǒng)其他部分交互的功能。這樣說來,建立可靠的分布式系統(tǒng)最的問題并不是使用過程調(diào)用的系統(tǒng)所關(guān)注的:把數(shù)據(jù)轉(zhuǎn)化為可移植的格式、調(diào)用網(wǎng)絡(luò)上的過程等,相反,建立可靠的分布式系統(tǒng)最的是那些程序員不能忽略的網(wǎng)絡(luò)事實— 資源用的時間比本地相同的資源大許多,網(wǎng)絡(luò)會出現(xiàn)獨立系統(tǒng)不存在的方式,網(wǎng)絡(luò)系統(tǒng)中的一部分出現(xiàn)故障時會導(dǎo)致系統(tǒng)處于不一致的狀態(tài),這些問題需要認真處理。計算機PeterDeutsch很多年前就認識到了這一問題,并列出了關(guān)于分布式計算的七個錯誤認識,我們在工具條中給出了他的觀點,在這里不再詳細。即使使用一些經(jīng)典的系統(tǒng),創(chuàng)建可靠的、可伸縮的、健壯的分布式系統(tǒng)仍然十分,這也是我們經(jīng)常在網(wǎng)絡(luò)上看到如此多錯誤信息的原因。經(jīng)典的網(wǎng)絡(luò)系統(tǒng)“”了無知的人們,使他們相信可以忽略某些實際并不能隱藏的問題,從而使分布式系統(tǒng)編程中潛伏了很多這樣的問題。下面我們逐步展開。計算機PeterDeutsch早就對被他稱為“分布式計算的七個錯誤”的相關(guān)問題進?顯然,通過網(wǎng)絡(luò)資源,如一個文件或一個對象,要比本地的慢。從時間上看,它們之間的差別常是幾個數(shù)量級,可以說它們之間不再僅是量的差別,而是質(zhì)的差別。?Cache要比主存快幾個數(shù)量級,而主存要比磁盤快幾個數(shù)量級,這難道不能看作是性能等級的另一個層次?”這里問題的關(guān)鍵在于,網(wǎng)絡(luò)系統(tǒng)中的性能差別太大,以致于系統(tǒng)常難以區(qū)別究竟是連接失敗還是過慢。盡管主存比磁盤的速度快,但二者的性能參數(shù)都能保持在一定的范圍內(nèi),使用過eb瀏覽器的人都有過體會,網(wǎng)絡(luò)的性能差別特別大,即使在一小段時間內(nèi)也是如此。本地系統(tǒng)中的時間不會像時間那樣影響程序。RPC和CORBA這樣的系統(tǒng)并沒有考慮這些性能問題。這里我并不是說要它們把網(wǎng)絡(luò)性能提高成百上千倍以減弱延遲上的差別,實際上它們也做不到;但是RPC和CORBA把性能和延遲當(dāng)作它們編程模型的一部分,就帶來了一些麻煩,它們只是簡單地完全忽略掉這個問題,把它當(dāng)作是程序員要認識到并進行處理的部分。如果在開發(fā)時忽略掉這些差別(因為 和本地方式十分相近,就意味著在分布式系統(tǒng)中不僅會出現(xiàn)性能極差的設(shè)計,而且可能出現(xiàn)不能夠處理網(wǎng)絡(luò)中性能差異的設(shè)計。如果一個系統(tǒng)在設(shè)計對象的接口之前未考慮本地或的“實現(xiàn)細節(jié)”,那么這個系統(tǒng)的通信模型就會特別慢,而且不夠健壯。須要在考慮對象間通口的設(shè)計時就考慮這類“”結(jié)構(gòu)的細節(jié),到設(shè)新形網(wǎng)絡(luò)系統(tǒng)存在一些獨立系統(tǒng)中沒有形式:路由器可能失敗,用戶會有意或無意地把網(wǎng)線從墻中扯出,運行服務(wù)器或數(shù)據(jù)庫服務(wù)器的關(guān)鍵機器可能等等。如果把在獨立環(huán)境中編寫的代碼放在網(wǎng)絡(luò)環(huán)境中運行,它們會對這些新失敗形式產(chǎn)生的無所適從。舉一個簡單的例子:一個從磁盤上文件的函數(shù)。這個程序段在一個大的應(yīng)用中重復(fù)運行,把文件以電子表格的形式顯示出來,并可以按原來的設(shè)定正確地寫入。這個程序可以智能地檢測并處理各類錯誤,包括文件系統(tǒng)溢出、權(quán)違例等等?,F(xiàn)在考慮運行這樣一個應(yīng)用程序,它用來處理網(wǎng)絡(luò)文件服務(wù)器磁盤上的文件。原來它可以智能地處理本地的各類故障,現(xiàn)在卻必須面對各種網(wǎng)絡(luò)故障。文件服務(wù)器主機可能關(guān)閉,或是不能到。在有些情況下,應(yīng)用程序可能會像對待本地錯誤時一樣以“正常的”方式退出,例如它可能會像對待權(quán)一樣對待服務(wù)器關(guān)閉的情形,但是它也極有可能會以不可預(yù)料的方式:這個程序當(dāng)然不能智能地處理網(wǎng)絡(luò)錯誤,如在服務(wù)器不可達時重試,或是在主文件服務(wù)器故障時提示使用后備文件服務(wù)器。生,包括網(wǎng)絡(luò)。這就像在本地系統(tǒng)中,做完磁盤寫操作后檢查一下數(shù)據(jù)是否確實已正確地寫在。在本地系統(tǒng)中,可以試著向磁盤寫入一些數(shù)據(jù)然后檢查一下數(shù)據(jù)是否被正確寫入,但是在分布式系統(tǒng)中,通常沒有中心機構(gòu)(就像本地的操作系統(tǒng))來判斷是成功還是失敗,即使TCP/IPTCP/IP多么可靠,它不能區(qū)別一個應(yīng)用程序到底是了還是因為太慢沒有反應(yīng),沒有集中的機制作出判斷。如果系統(tǒng)在其接口中不考慮在網(wǎng)絡(luò)環(huán)境中可能出現(xiàn),那么這種“隱藏網(wǎng)絡(luò)”的編程模型實際上是默許了程序員可以忽略網(wǎng)絡(luò)故障;而如果能在接口中體現(xiàn)出 對象可能存在的問題,我們就可以強制程序員—通過編譯器—來注意這些問題。在本地和計算各方面的差別中,性能和延遲的差異以及故障形式的差異是十分明顯的,但分布式計算中特有的并行性和一致性問題帶來的影響要更為嚴(yán)重些。在本地系統(tǒng)中,如果一個實體出現(xiàn)故障,這種故障或者是全局性的,或者無甚關(guān)系。如果整個機器停機,那么只是該機器上的程序停止工作,與網(wǎng)絡(luò)上其他機器沒有關(guān)系,如果協(xié)同操作的一組應(yīng)用中的一個出現(xiàn)故障,比如剪貼操作中的一兩個應(yīng)用程序出錯,中心控制系統(tǒng)如操作系統(tǒng)就可以檢測到這樣的錯誤并通知其他相關(guān)部分。在分布式計算的情況下就不再是這種情形。在分布式系統(tǒng)中經(jīng)常是,某一部分出現(xiàn)故障而其他部分繼續(xù)運行,感覺不到這一部分。這種情況被稱為部分失?。╬artialfailure,是分布式計算中各種問題的主要根源,潛伏性強。全局失?。╰otalfailure)和本地系統(tǒng)中的情形差不多,因為系統(tǒng)終究是以一個確定的狀態(tài)結(jié)束,所以容易處理些。下面來看一個白板應(yīng)用程序的例子。這個程序允許網(wǎng)絡(luò)上的一組參加者作出標(biāo)記,共享一個公共的畫圖區(qū)。在一個用戶作出標(biāo)記后,這個更新情況應(yīng)該迅速地傳送出去或者通過多次單點傳送,即向每個參與者重復(fù)發(fā)送相同的信息,或者是通過組播,即一次把信息傳送到許多在網(wǎng)絡(luò)上的特定地址。無論在哪種情況下,接收方的計算機都可能在更新的過程中出現(xiàn)故障或者是不可到達。那么會出現(xiàn)什么情況呢?如果發(fā)送者不能檢測到這類故障(可能是因為寫例程原來是用于獨立系統(tǒng),或者是因為操作系統(tǒng)不能判斷消息是否已經(jīng)發(fā)出,那么就沒有辦法知道有一個參與者的信息與其他人的內(nèi)容不同步。如果一段時間后網(wǎng)絡(luò)又恢復(fù)正常,未接收到更新的程序繼續(xù)運行,根本不知道自己錯過了一次更新。你可能會想,只要保證發(fā)送者可以知道一個消息沒有被正確接收就可以了,即使操作系統(tǒng)不支持,應(yīng)用程序開發(fā)者也可以用附加序列號以及確認報文的方式判斷是否接收到了更新內(nèi)容(實際上可用的協(xié)議要比這復(fù)雜,因為發(fā)出確認消息的一方仍無法知道自己的確認消息是否被正確接收。即使是如此,最初的發(fā)送者在檢測到更新未被發(fā)送給接收方時又能做些什么?一種強硬的做法就是判定此接收方已經(jīng)而且不能恢復(fù),使這個參與者退出會話;而一種比較委婉的做法就是發(fā)送方保留更新的內(nèi)容,期待著這個接收者會重新連到網(wǎng)絡(luò)中,然后重新發(fā)送更新內(nèi)容。不過這些更新內(nèi)容要保存多久呢,接收恢復(fù)前的所有內(nèi)容嗎?我們當(dāng)然不希望一直為某個情況不明的接收方保留所有的消息,因為這樣會使發(fā)送方為一個非本地的錯誤耗去很多資源。這個共享白板應(yīng)用程序的例子很小,但它說明了把分布式開發(fā)的復(fù)雜問題隱會帶來很多問題。就像性能及失敗形式所帶來的影響一樣,部分失敗以及各部分間的一致性也帶來很多不利因素,在進行分布式編程時必須慎重對待。過去的方案只是試圖隱去本地和計算的差別,對這些問題不加考慮。當(dāng)然事實上它們也不可能解決這些問題:在出現(xiàn)部分失敗或一致性時,應(yīng)該是每個應(yīng)用程序開發(fā)者決定如何處理,而不應(yīng)該交給操作系統(tǒng)或工具套件,對所有應(yīng)用程序使用一種通用的方式。每個應(yīng)用程序都有不同的需要,因此需要以不同的方式處理部分失敗,一個必須要求完全一致性的應(yīng)用程序在檢測到不能保證恢復(fù)的部分失敗時,只要簡單地關(guān)閉應(yīng)用;而另外一些應(yīng)用程序也許能夠部分失敗的存在,也可能只允許在一小段時間內(nèi)存在??傊?,系統(tǒng)在處理部分失敗時一定要依賴于每個應(yīng)用程序的實現(xiàn)方式,程序員必須在自己的系統(tǒng)中認清并處理這些故障。因此,分布式系統(tǒng)的開發(fā)者必須清楚網(wǎng)絡(luò)編程和本地編程間的差別,慎重選擇最適合自己應(yīng)用需求的方案,或決定作出某些折衷。盡管分布式系統(tǒng)的研究已經(jīng)開展了30年,創(chuàng)建分布式的仍然十分,原因在于過去的工作集中于數(shù)據(jù)的可移植性以及如何把數(shù)據(jù)轉(zhuǎn)移到計算的場所,而這些并非最的問題。盡管不能解決所有問題,Java還是在這些使分布式系統(tǒng)編程變得的問題上取得了很大的進步。首先,Java很好地解決了經(jīng)典系統(tǒng)所關(guān)注的大部分問題,而還有一些原來的問題在Java中根本就不必考慮,因為Java是一種面向語言的系統(tǒng),整個Java平臺,包括JVM、類庫、字節(jié)碼驗證器、安全體系結(jié)構(gòu)等,都以Java字節(jié)碼解釋所有的對象,這種方式可以從很多方面簡化分布式系統(tǒng)的創(chuàng)建工作。在 及 這樣的系統(tǒng)中,分布式特性是基于一種或多種語言的固定附件,而Java的方案是假定這種特別的語言無處不在,數(shù)據(jù)格式和代碼格式都完全。這樣數(shù)據(jù)轉(zhuǎn)移就不再有什么問題?;绢愋腿缯?、浮點數(shù)、字符串、數(shù)組,甚至還有對象的大小和格式,都嚴(yán)格按Java規(guī)范進行定義,不需要特殊的機制在一臺機器的數(shù)據(jù)格式與另一臺機器的數(shù)據(jù)格式之間進行轉(zhuǎn)換。C語言就完全不同,其語言本身未對本數(shù)據(jù)類型的大小和格式作明確規(guī)定,我們只能依靠語言之外的工具來描述可移植的數(shù)據(jù)。除了定義基本類型外,Java還定義了完整對象的格式,包括子類化、方法保護屬性、類型標(biāo)記等的細節(jié)。定義如此詳盡的數(shù)據(jù),是為適應(yīng)XDR等把數(shù)據(jù)為可移植類型的機制。另外,在Java出現(xiàn)前關(guān)于分布式計算的一個最主要的假設(shè),即把數(shù)據(jù)移向代碼(相反的操作不可行,也已失去意義。使用Java,代碼可以方便地在機器間轉(zhuǎn)移,即使是操作系統(tǒng)或CPU比較特殊的機器也無所謂。當(dāng)然移動數(shù)據(jù)也沒有問題。對于可執(zhí)行代碼,Java的字節(jié)碼格式是于換的格。另外,Java的安全機制可以保證轉(zhuǎn)移到本地機器上的代碼可以在高度的安全性下執(zhí)行,其他方法做不到這點。或許操作系統(tǒng)可以通過共享對象文件或動態(tài)庫的方式支持動態(tài)代碼段,如C代碼,但是Java的安全動態(tài)加載工具可以更好地支持,Java通過安全策略可支持對系統(tǒng)資源細粒度的控制,代碼可使用數(shù)字位標(biāo)注,為類的來源提供加密的安全保證。更重要的是,Java的強類型的安全性以及字節(jié)碼驗證器的能力,可以保證不良的代碼不會被運行。也就是說,在運行 的代碼時,可保證引起整個系統(tǒng)的機率非常小。例如,在C語言中,如果動態(tài)加載的代碼段中有空指針,或是提Java中,不存在對未使用數(shù)據(jù)的,而且不可能把新的強加到未被明確給以的對象上。另外,在C中一個函數(shù)可能會返回些任意的值(也不是期望的)來標(biāo)識錯誤情況,而在Java中,異常的情況必須作為方法一部分,強制那些調(diào)用此代碼的程序處理。這種安全屬性使Java可限制動態(tài)加載的代碼破壞整個系統(tǒng)??梢栽跈C器之間轉(zhuǎn)移代碼是一個偉大的變化,這樣,服務(wù)器就可以動態(tài)更新,可以在被的客戶端進行。Agent代碼可以在網(wǎng)絡(luò)中移動,靠近所需的代碼以提高性能。建立在如此看來,在那些過去的系統(tǒng)所關(guān)注的許多問題上,Java確實提供了一些新的方案,而且還使過去的系統(tǒng)中關(guān)心的另一些問題不再需要考慮。但對于我們在本章開始部分所的分布式算那些真正的問題,Java?Java是如何區(qū)別對待有本質(zhì)區(qū)別的本地和對象的呢?在理解Java如何解決這些難題之前,下面先來看看用于Java的強類型分布式計算模型。我們將會了解到,Java并沒有提供特別的方法解決上述問題,Java的分布式計算模型明確認可本地和計算過程的差異,并提供一個支持編程解決這些問題的工具集。需要強類前面一部分主要是Java支持把代碼發(fā)送到需要運行的場所的能力,但這確實是我們需要的嗎?一個可執(zhí)行代碼滿天飛的環(huán)境就真的易于和管理嗎?作為一種基于語言的方,Java可以充分利用本地系統(tǒng)中強類型、真正的面象、以及多態(tài)性帶來的好處,并把這些優(yōu)點擴展到Internet在方法調(diào)用(RMI時,Java語言的類型定義系統(tǒng)通信的接口。這看起來不太重要,事實并非如此—Java類或接口時所創(chuàng)建的本地類型以及Java類庫中的類型,與用于通信的類型是采用完全相同的機制定義的,也就是說,用于和服務(wù)器進行通信的協(xié)議,其實就是Java接口,可以通過一個類來實現(xiàn)。下面是一個接口定義的例子,它出現(xiàn)在使用JavaRMIpublicinterfaceRemoteServerextendspublicintgetLength(Strings)throws}這個例子實際上是在定義兩個進程間的“協(xié)議”,它定義了兩個進程間相互作用的術(shù)語,包括發(fā)送什么、可做什么操作、可得到什么結(jié)果。當(dāng)然這個協(xié)議要在運行其他低層協(xié)議如TCP/IP的基礎(chǔ)上實現(xiàn)(RMI將處理所有建立、撤銷套接字等便利的操作,而這里的定義給兩個進程如何在應(yīng)用級進行通信提供了規(guī)約??傮w上看,這個例子說客戶端可以發(fā)送一個傳送字符串的消息到的服務(wù)器,服務(wù)器返回一個整數(shù)作為對消息的應(yīng)答。這個例子還在Java語言中定義了一個一級接口,這才是RMI的關(guān)鍵所在。這個一級接口可以由類來實現(xiàn),通過多接口繼承、作為參數(shù)傳送、從方法中返回、自?。╥ntrospect,由其他多個接口構(gòu)的,RMI完全使用類型來定義協(xié)議,Java語言中隨意修改類型以擴展或改變協(xié)議,而像IDL那樣的系統(tǒng)是使用協(xié)議的一些外部表示來描述協(xié)議的“真理”(經(jīng)常是用中性語言的形式來定義協(xié)議。協(xié)議以JavaJava類型只不過是協(xié)議定義的映像,IDL規(guī)范的Java類型,絲毫不會改變IDL中用于通信的協(xié)議。這些不同之處看起來比較微妙,而且有些學(xué)術(shù)性的味道,但它的重要性不容低估。通過在新型面象語言中以一級對象的方式定義協(xié)議,可以極大地發(fā)揮面象的優(yōu)勢,使其在分布式計算環(huán)境中仍能像在單地址空間中一樣正常工作。多態(tài)性也依然存在,例如我可以定義一個接口是其他接口的子接口。多態(tài)性的規(guī)則依然適用,我們可以傳送一個更通用的接口,在需要的時候?qū)⑵渫渡涞礁慕涌谏?,然后在運行時使用instanceof來檢查一下實際是使用了哪一個接口。就像接口可以有多種實現(xiàn)方式一樣,可以為一個特殊的接口實現(xiàn)多個Java類,編譯器將強制開發(fā)者以正確的方式實現(xiàn)所需的方法。就像可以編寫實現(xiàn)多個本地接口的類一樣,我們也可以編寫實現(xiàn)多個多態(tài)性比在接口中支持多態(tài)性更進一步的是,對于作為參數(shù)傳送給方法或作為方RMI也支持完全的多態(tài)性。我們來看一下這樣一段例子代碼:publicinterfaceMatrixSolverRemote{publicMatrixcrossProduct(Matrixm1,Matrixm2)throws}這段代碼定義了一個用于矩陣計算的接口(假設(shè)實現(xiàn)這個接口的對象運行在高端處理器上,它處理矩陣計算十分快,接收參數(shù)和發(fā)送結(jié)果的時間與可節(jié)省的時間相比小得多,這個接口接收兩個MatrixMatrix顯然設(shè)計者希望調(diào)用者接收和發(fā)送Matrix類型的對象,并可以理解這個類的定義。假,為SparseMatrix,標(biāo)準(zhǔn)的Matrix類的子類,它的數(shù)據(jù)項更少,但效率更高,因此我在自己程序中全部使用它。不過我希望能利用的矩陣計算對象,因為它們運行在高性能的機器上,不幸的是這個程序由其他的小組開發(fā),只認識基本的Matrix類,不能識別SparseMatrix類。顯然,在本地系統(tǒng)情形下,Java類型的多態(tài)性可以幫助我解決問題:我仍然把SparseMatrix實例傳遞給只識別普通MatrixcrossProduct()函數(shù)可以正常工作,因為它只使用類中的Matrix部分。更好的crossProduct()函數(shù)甚至?xí){(diào)用clone()例程來它的一個輸入?yún)?shù)以創(chuàng)建一個相同類型的對象用于填寫返回的結(jié)果,那樣的話返回的結(jié)果就和輸入是相同的類型了。但是在系統(tǒng)的情況下如何呢?如果使用RMI,就會和本地系統(tǒng)完全一樣,即使的矩陣計算服務(wù)器不知道SparseMatrix類,而且機器上也沒有這個類的代碼,RMI也會把一個SparseMatrix實例和數(shù)據(jù)一起打包發(fā)送到。重要的是, 碼傳送出去,這樣可以確保SparseMatrix作為Matrix的一個子類實現(xiàn)所有需要的方法,從而可以在需要使用Matrix類時安全可靠地使用SparseMatrix類。這是一個十分實用的例子。動態(tài)可移動的代碼不僅在新興的應(yīng)用如主動Agent中有用,而且對于把面象編程擴展到網(wǎng)絡(luò)系統(tǒng)具有重要的作用。特性是接口的一部分而與實現(xiàn)在上面一節(jié)那個短小的例子中,還可以注意到RMI帶來的另外一個好處—一個對象的“特性”,即可在其他地址空間使用的特點,只是對象接口的一部分。這是與主流不同的另一個巧妙變化,它強迫開發(fā)者從一開始就考慮程序的特性,而不是稍后再添加,這種選擇使得程序員必須事先考慮好他們的應(yīng)用要采用哪種通信模式。一個方法的特性必須被明確,而不能作為對象實現(xiàn)的一部分被隱。而且就像 Java類型系統(tǒng)中的其他類型一樣,一個對象的特性可在編譯時被強制轉(zhuǎn)換類型,然后在運行時自省。RMI要求所有定義了通信協(xié)議的接口都要擴展接口javarmi.Remote,這個接口對所有可使用的對象是公共的,因此在編譯或運行時可以很容易地判斷一個對象是否支持使用。這些對象和簡單的本地對象有著不同的語義,比如它們對相等的理解就不相同。在遠程對象中,兩個對象相等是基于兩個對象是否指向了某個服務(wù)器上的同一個對象,而不是指這兩個對象是否為同一個。也就是說,如果你了一個對象,而事實上指向的是那個對象在本地的,稱為“存”,那么在比較兩個時,你并不關(guān)心它們是否指向了象。因此在系統(tǒng)中相等的概念被擴展了。或許更重要的是,每一個可調(diào)用的對象中的方法都產(chǎn)生異常java.rmi.Rem-oteException。這個異常和它的子類一起,定義了在網(wǎng)絡(luò)環(huán)境中可能出現(xiàn)形式。通過在方法的標(biāo)記中明確這些失敗情況,RMI強制那些使用對象的程序員要提供處理這些異常情況的代碼以應(yīng)付失敗的發(fā)生。因為Java異常為方法標(biāo)記中的一部分,因此調(diào)用代碼的程序要么是自己處理各類異常,要么是把這些異常向上到可處理的程序,編譯器不允許程序員忽略掉這些情形。方法調(diào)用RMI當(dāng)然不是萬能的,因此它不能解決分布式系統(tǒng)中所有的問題,或是使得建立分布式系統(tǒng)像建立本地系樣簡單,但它的思路是正確的。RMI使用Java類型系統(tǒng),但對本地和對象的語義進行了區(qū)分。它強制開發(fā)處理分布式環(huán)境可能出現(xiàn)的故障,要求他們把分布式明確地而不是在實現(xiàn)中隱藏。為利用Java,RMI類型,并擴展到網(wǎng)域。RMI使得數(shù)據(jù)可移植性不再成為一個問題,而且通過支持安全代碼的概念,RMI把面象編程的優(yōu)點到了網(wǎng)絡(luò)系統(tǒng),支持靈活可伸縮的代碼RMI還提供了一個功能強大的工具包,用于幫助開發(fā)者解決在創(chuàng)建分布式應(yīng)用時可能遇到的問題。當(dāng)然,Java因可移動代碼而著名,但它不僅僅是用于RMI環(huán)境中,下面這個工具條用于比較可移動代碼在RMI中的應(yīng)用和在其他情況下的應(yīng)用。面幾節(jié)舉了幾個例子說明可移動代碼的用處,這些例子與可移動代碼在其他上下文中的應(yīng)用相比較如何呢,如Applet?下面總結(jié)了一些使用可移動代碼的上下文,Applet:是Java最著名的一部分內(nèi)容。使用pplt,小應(yīng)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 智能化系統(tǒng)安裝工程合同書
- 水利水電工程勞務(wù)承包合同
- 土地使用權(quán)征收補償合同協(xié)議
- 影視劇本供應(yīng)與購買合同書版
- 規(guī)范化離婚合同文本范文
- 采購合同簡版-鋼材專項
- 婦科培訓(xùn)課件模板
- 小學(xué)生唱音階課件圖片
- 公證員網(wǎng)絡(luò)知識產(chǎn)權(quán)考核試卷
- 墨水制備實驗室建設(shè)與管理考核試卷
- 供應(yīng)鏈管理課件第5章供應(yīng)鏈合作伙伴選擇與評價
- 4D現(xiàn)場管理培訓(xùn)ppt課件(PPT 45頁)
- 餐飲店面投資預(yù)算(900平方米)
- 預(yù)應(yīng)力工程施工質(zhì)量驗收標(biāo)準(zhǔn)
- 檢驗科危急值管理.
- 旅游資源規(guī)劃與開發(fā)實訓(xùn)指導(dǎo)書
- 立體幾何專題:距離和角
- DBJ-T01-43-2003_(北京)通用家庭居室裝飾工程質(zhì)量驗收標(biāo)準(zhǔn)
- 16949客戶滿意度調(diào)查分析報告
- 生產(chǎn)線外包方案
- 2.通信光纜線路(管道)工程施工及驗收技術(shù)規(guī)程要點
評論
0/150
提交評論