成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識庫 > Java線程模型缺陷

Java線程模型缺陷

熱門標(biāo)簽:商丘百應(yīng)電話機器人有沒有效果 開封便宜外呼系統(tǒng)報價 淮南騰訊地圖標(biāo)注 地圖標(biāo)注人員兼職 騰訊地圖標(biāo)注商戶改名注冊入駐 怎樣把地圖標(biāo)注出來 黃石智能營銷電銷機器人效果 漯河辦理400電話 電話機器人的特色和創(chuàng)新

  Java 編程語言的線程模型可能是此語言中最薄弱的部分。它完全不適合實際復(fù)雜程序的要求,而且也完全不是面向?qū)ο蟮?。本文建議對 Java 語言進行重大修改和補充,以解決這些問題。

  Java 語言的線程模型是此語言的一個最難另人滿意的部分。盡管 Java 語言本身就支持線程編程是件好事,但是它對線程的語法和類包的支持太少,只能適用于極小型的應(yīng)用環(huán)境。

  關(guān)于 Java 線程編程的大多數(shù)書籍都長篇累牘地指出了 Java 線程模型的缺陷,并提供了解決這些問題的急救包(Band-Aid/邦迪創(chuàng)可貼)類庫。我稱這些類為急救包,是因為它們所能解決的問題本應(yīng)是由 Java 語言本身語法所包含的。從長遠(yuǎn)來看,以語法而不是類庫方法,將能產(chǎn)生更高效的代碼。這是因為編譯器和 Java 虛擬器 (JVM) 能一同優(yōu)化程序代碼,而這些優(yōu)化對于類庫中的代碼是很難或無法實現(xiàn)的。

  Allen Holub 指出,在我的《Taming Java Threads 》(請參閱 參考資料 )書中以及本文中,我進一步建議對 Java 編程語言本身進行一些修改,以使得它能夠真正解決這些線程編程的問題。本文和我這本書的主要區(qū)別是,我在撰寫本文時進行了更多的思考, 所以對書中的提議加以了提高。這些建議只是嘗試性的 -- 只是我個人對這些問題的想法,而且實現(xiàn)這些想法需要進行大量的工作以及同行們的評價。但這是畢竟是一個開端,我有意為解決這些問題成立一個專門的工作組,如果您感興趣,請發(fā) e-mail 到 threading@holub.com 。一旦我真正著手進行,我就會給您發(fā)通知。

  這里提出的建議是非常大膽的。有些人建議對 Java 語言規(guī)范 (JLS)(請參閱參考資料 )進行細(xì)微和少量的修改以解決當(dāng)前模糊的 JVM 行為,但是我卻想對其進行更為徹底的改進。

  在實際草稿中,我的許多建議包括為此語言引入新的關(guān)鍵字。雖然通常要求不要突破一個語言的現(xiàn)有代碼是正確的,但是如果該語言的并不是要保持不變以至于過時的話,它就必須能引入新的關(guān)鍵字。為了使引入的關(guān)鍵字與現(xiàn)有的標(biāo)識符不產(chǎn)生沖突,經(jīng)過細(xì)心考慮,我將使用一個 ($) 字符,而這個字符在現(xiàn)有的標(biāo)識符中是非法的。(例如,使用 $task,而不是 task)。此時需要編譯器的命令行開關(guān)提供支持,能使用這些關(guān)鍵字的變體,而不是忽略這個美元符號。

  task(任務(wù))的概念

  Java 線程模型的根本問題是它完全不是面向?qū)ο蟮摹C嫦驅(qū)ο?(OO) 設(shè)計人員根本不按線程角度考慮問題;他們考慮的是同步 信息 異步 信息(同步信息被立即處理 -- 直到信息處理完成才返回消息句柄;異步信息收到后將在后臺處理一段時間 -- 而早在信息處理結(jié)束前就返回消息句柄)。Java 編程語言中的 Toolkit.getImage() 方法就是異步信息的一個好例子。 getImage() 的消息句柄將被立即返回,而不必等到整個圖像被后臺線程取回。

  這是面向?qū)ο?(OO) 的處理方法。但是,如前所述,Java 的線程模型是非面向?qū)ο蟮摹R粋€ Java 編程語言線程實際上只是一個run() 過程,它調(diào)用了其它的過程。在這里就根本沒有對象、異步或同步信息以及其它概念。

  對于此問題,在我的書中深入討論過的一個解決方法是,使用一個Active_object。 active 對象是可以接收異步請求的對象,它在接收到請求后的一段時間內(nèi)以后臺方式得以處理。在 Java 編程語言中,一個請求可被封裝在一個對象中。例如,你可以把一個通過 Runnable 接口實現(xiàn)的實例傳送給此 active 對象,該接口的 run() 方法封裝了需要完成的工作。該 runnable 對象被此 active 對象排入到隊列中,當(dāng)輪到它執(zhí)行時,active 對象使用一個后臺線程來執(zhí)行它。

  在一個 active 對象上運行的異步信息實際上是同步的,因為它們被一個單一的服務(wù)線程按順序從隊列中取出并執(zhí)行。因此,使用一個 active 對象以一種更為過程化的模型可以消除大多數(shù)的同步問題。

  在某種意義上,Java 編程語言的整個 Swing/AWT 子系統(tǒng)是一個 active 對象。向一個 Swing 隊列傳送一條訊息的唯一安全的途徑是,調(diào)用一個類似SwingUtilities.invokeLater() 的方法,這樣就在 Swing 事件隊列上發(fā)送了一個 runnable 對象,當(dāng)輪到它執(zhí)行時, Swing 事件處理線程將會處理它。

  那么我的第一個建議是,向 Java 編程語言中加入一個task (任務(wù))的概念,從而將active 對象集成到語言中。( task的概念是從 Intel 的 RMX 操作系統(tǒng)和 Ada 編程語言借鑒過來的。大多數(shù)實時操作系統(tǒng)都支持類似的概念。)

  一個任務(wù)有一個內(nèi)置的 active 對象分發(fā)程序,并自動管理那些處理異步信息的全部機制。

  定義一個任務(wù)和定義一個類基本相同,不同的只是需要在任務(wù)的方法前加一個asynchronous 修飾符來指示 active 對象的分配程序在后臺處理這些方法。

  所有的寫請求都用一個dispatch() 過程調(diào)用被放在 active-object 的輸入隊列中排隊。在后臺處理這些異步信息時出現(xiàn)的任何異常 (exception) 都由 Exception_handler 對象處理,此 Exception_handler 對象被傳送到 File_io_task 的構(gòu)造函數(shù)中。

  這種基于類的處理方法,其主要問題是太復(fù)雜了 -- 對于一個這樣簡單的操作,代碼太雜了。向 Java 語言引入$task 和 $asynchronous 關(guān)鍵字后,就可以按下面這樣重寫以前的代碼:

  注意,異步方法并沒有指定返回值,因為其句柄將被立即返回,而不用等到請求的操作處理完成后。所以,此時沒有合理的返回值。對于派生出的模型,$task 關(guān)鍵字和 class 一樣同效: $task 可以實現(xiàn)接口、繼承類和繼承的其它任務(wù)。標(biāo)有 asynchronous 關(guān)鍵字的方法由 $task 在后臺處理。其它的方法將同步運行,就像在類中一樣。

  $task關(guān)鍵字可以用一個可選的 $error 從句修飾 (如上所示),它表明對任何無法被異步方法本身捕捉的異常將有一個缺省的處理程序。我使用 $ 來代表被拋出的異常對象。如果沒有指定 $error 從句,就將打印出一個合理的出錯信息(很可能是堆棧跟蹤信息)。

  注意,為確保線程安全,異步方法的參數(shù)必須是不變 (immutable) 的。運行時系統(tǒng)應(yīng)通過相關(guān)語義來保證這種不變性(簡單的復(fù)制通常是不夠的)。

  所有的 task 對象必須支持一些偽信息 (pseudo-message)。

  除了常用的修飾符(public 等), task 關(guān)鍵字還應(yīng)接受一個 $pooled(n) 修飾符,它導(dǎo)致 task 使用一個線程池,而不是使用單個線程來運行異步請求。 n 指定了所需線程池的大??;必要時,此線程池可以增加,但是當(dāng)不再需要線程時,它應(yīng)該縮到原來的大小。偽域 (pseudo-field) $pool_size 返回在 $pooled(n) 中指定的原始 n 參數(shù)值。

  在《Taming Java Threads 》的第八章中,我給出了一個服務(wù)器端的 socket 處理程序,作為線程池的例子。它是關(guān)于使用線程池的任務(wù)的一個好例子。其基本思路是產(chǎn)生一個獨立對象,它的任務(wù)是監(jiān)控一個服務(wù)器端的 socket。每當(dāng)一個客戶機連接到服務(wù)器時,服務(wù)器端的對象會從池中抓取一個預(yù)先創(chuàng)建的睡眠線程,并把此線程設(shè)置為服務(wù)于客戶端連接。socket 服務(wù)器會產(chǎn)出一個額外的客戶服務(wù)線程,但是當(dāng)連接關(guān)閉時,這些額外的線程將被刪除。

  Socket_server對象使用一個獨立的后臺線程處理異步的 listen() 請求,它封裝 socket 的“接受”循環(huán)。當(dāng)每個客戶端連接時, listen() 請求一個 Client_handler 通過調(diào)用 handle() 來處理請求。每個 handle() 請求在它們自己的線程中執(zhí)行(因為這是一個 $pooled 任務(wù))。

  注意,每個傳送到$pooled $task 的異步消息實際上都使用它們自己的線程來處理。典型情況下,由于一個 $pooled $task 用于實現(xiàn)一個自主操作;所以對于解決與訪問狀態(tài)變量有關(guān)的潛在的同步問題,最好的解決方法是在 $asynchronous 方法中使用 this 是指向的對象的一個獨有副本。這就是說,當(dāng)向一個 $pooled $task 發(fā)送一個異步請求時,將執(zhí)行一個 clone() 操作,并且此方法的 this 指針會指向此克隆對象。線程之間的通信可通過對 static 區(qū)的同步訪問實現(xiàn)。

   改進synchronized

  雖然在多數(shù)情況下,$task 消除了同步操作的要求,但是不是所有的多線程系統(tǒng)都用任務(wù)來實現(xiàn)。所以,還需要改進現(xiàn)有的線程模塊。 synchronized 關(guān)鍵字有下列缺點: 無法指定一個超時值。 無法中斷一個正在等待請求鎖的線程。 無法安全地請求多個鎖 。(多個鎖只能以依次序獲得。)

  解決這些問題的辦法是:擴展synchronized 的語法,使它支持多個參數(shù)和能接受一個超時說明(在下面的括弧中指定)。下面是我希望的語法:


  synchronized(x y z)獲得 x、y 和 z 對象的鎖。
  synchronized(x || y || z)獲得 x、y 或 z 對象的鎖。
  synchronized( (x y ) || z)對于前面代碼的一些擴展。
  synchronized(...)[1000] 設(shè)置 1 秒超時以獲得一個鎖。
  synchronized[1000] f(){...}在進入 f() 函數(shù)時獲得 this 的鎖,但可有 1 秒超時。


  TimeoutException是 RuntimeException 派生類,它在等待超時后即被拋出。

  超時是需要的,但還不足以使代碼強壯。您還需要具備從外部中止請求鎖等待的能力。所以,當(dāng)向一個等待鎖的線程傳送一個interrupt() 方法后,此方法應(yīng)拋出一個 SynchronizationException 對象,并中斷等待的線程。這個異常應(yīng)是 RuntimeException 的一個派生類,這樣不必特別處理它。

  對synchronized 語法這些推薦的更改方法的主要問題是,它們需要在二進制代碼級上修改。而目前這些代碼使用進入監(jiān)控(enter-monitor)和退出監(jiān)控(exit-monitor)指令來實現(xiàn) synchronized 。而這些指令沒有參數(shù),所以需要擴展二進制代碼的定義以支持多個鎖定請求。但是這種修改不會比在 Java 2 中修改 Java 虛擬機的更輕松,但它是向下兼容現(xiàn)存的 Java 代碼。

  另一個可解決的問題是最常見的死鎖情況,在這種情況下,兩個線程都在等待對方完成某個操作。

  設(shè)想一個線程調(diào)用a() ,但在獲得  lock1 之后在獲得 lock2 之前被剝奪運行權(quán)。 第二個線程進入運行,調(diào)用 b() ,獲得了 lock2 ,但是由于第一個線程占用 lock1 ,所以它無法獲得 lock1 ,所以它隨后處于等待狀態(tài)。此時第一個線程被喚醒,它試圖獲得 lock2 ,但是由于被第二個線程占據(jù),所以無法獲得。此時出現(xiàn)死鎖。

  編譯器(或虛擬機)會重新排列請求鎖的順序,使lock1 總是被首先獲得,這就消除了死鎖。

  但是,這種方法對多線程不一定總成功,所以得提供一些方法來自動打破死鎖。一個簡單的辦法就是在等待第二個鎖時常釋放已獲得的鎖。

  如果等待鎖的每個程序使用不同的超時值,就可打破死鎖而其中一個線程就可運行。我建議用以下的語法來取代前面的代碼:

  synchronized語句將永遠(yuǎn)等待,但是它時常會放棄已獲得的鎖以打破潛在的死鎖可能。在理想情況下,每個重復(fù)等待的超時值比前一個相差一隨機值。
   改進wait() 和 notify()

  wait()/ notify() 系統(tǒng)也有一些問題: 無法檢測 wait() 是正常返回還是因超時返回。 無法使用傳統(tǒng)條件變量來實現(xiàn)處于一個“信號”(signaled)狀態(tài)。 太容易發(fā)生嵌套的監(jiān)控(monitor)鎖定。

  超時檢測問題可以通過重新定義wait() 使它返回一個 boolean 變量 (而不是 void ) 來解決。一個 true 返回值指示一個正常返回,而 false 指示因超時返回。

  基于狀態(tài)的條件變量的概念是很重要的。如果此變量被設(shè)置成false 狀態(tài),那么等待的線程將要被阻斷,直到此變量進入 true 狀態(tài);任何等待 true 的條件變量的等待線程會被自動釋放。 (在這種情況下, wait() 調(diào)用不會發(fā)生阻斷。)。

  嵌套監(jiān)控鎖定問題非常麻煩,我并沒有簡單的解決辦法。嵌套監(jiān)控鎖定是一種死鎖形式,當(dāng)某個鎖的占有線程在掛起其自身之前不釋放鎖時,會發(fā)生這種嵌套監(jiān)控封鎖。

  此例中,在get() 和 put() 操作中涉及兩個鎖:一個在 Stack 對象上,另一個在 LinkedList 對象上。下面我們考慮當(dāng)一個線程試圖調(diào)用一個空棧的 pop() 操作時的情況。此線程獲得這兩個鎖,然后調(diào)用 wait() 釋放 Stack 對象上 的鎖,但是沒有釋放在 list 上的鎖。如果此時第二個線程試圖向堆棧中壓入一個對象,它會在 synchronized(list) 語句上永遠(yuǎn)掛起,而且永遠(yuǎn)不會被允許壓入一個對象。由于第一個線程等待的是一個非空棧,這樣就會發(fā)生死鎖。這就是說,第一個線程永遠(yuǎn)無法從 wait() 返回,因為由于它占據(jù)著鎖,而導(dǎo)致第二個線程永遠(yuǎn)無法運行到 notify() 語句。

  在這個例子中,有很多明顯的辦法來解決問題:例如,對任何的方法都使用同步。但是在真實世界中,解決方法通常不是這么簡單。

  一個可行的方法是,在wait() 中按照反順序釋放當(dāng)前線程獲取的 所有 鎖,然后當(dāng)?shù)却龡l件滿足后,重新按原始獲取順序取得它們。但是,我能想象出利用這種方式的代碼對于人們來說簡直無法理解,所以我認(rèn)為它不是一個真正可行的方法。如果您有好的方法,請給我發(fā) e-mail。

  我也希望能等到下述復(fù)雜條件被實現(xiàn)的一天。例如:

  其中a 、 b 和 c 是任意對象。

  修改Thread 類

  同時支持搶占式和協(xié)作式線程的能力在某些服務(wù)器應(yīng)用程序中是基本要求,尤其是在想使系統(tǒng)達到最高性能的情況下。我認(rèn)為 Java 編程語言在簡化線程模型上走得太遠(yuǎn)了,并且 Java 編程語言應(yīng)支持 Posix/Solaris 的“綠色(green)線程”和“輕便(lightweight)進程”概念(在“(Taming Java Threads ”第一章中討論)。 這就是說,有些 Java 虛擬機的實現(xiàn)(例如在 NT 上的 Java 虛擬機)應(yīng)在其內(nèi)部仿真協(xié)作式進程,其它 Java 虛擬機應(yīng)仿真搶占式線程。而且向 Java 虛擬機加入這些擴展是很容易的。

  一個 Java 的Thread 應(yīng)始終是搶占式的。這就是說,一個 Java 編程語言的線程應(yīng)像 Solaris 的輕便進程一樣工作。 Runnable 接口可以用于定義一個 Solaris 式的“綠色線程”,此線程必需能把控制權(quán)轉(zhuǎn)給運行在相同輕便進程中的其它綠色線程。

  能有效地為Runnable 對象產(chǎn)生一個綠色線程,并把它綁定到由 Thread 對象代表的輕便進程中。這種實現(xiàn)對于現(xiàn)有代碼是透明的,因為它的有效性和現(xiàn)有的完全一樣。

  把Runnable 對象想成為綠色線程,使用這種方法,只需向 Thread 的構(gòu)造函數(shù)傳遞幾個 Runnable 對象,就可以擴展 Java 編程語言的現(xiàn)有語法,以支持在一個單一輕便線程有多個綠色線程。(綠色線程之間可以相互協(xié)作,但是它們可被運行在其它輕便進程 ( Thread 對象) 上的綠色進程( Runnable 對象) 搶占。)。例如,下面的代碼會為每個 runnable 對象創(chuàng)建一個綠色線程,這些綠色線程會共享由 Thread 對象代表的輕便進程。

  現(xiàn)有的覆蓋(override)Thread 對象并實現(xiàn) run() 的習(xí)慣繼續(xù)有效,但是它應(yīng)映射到一個被綁定到一輕便進程的綠色線程。(在 Thread() 類中的缺省 run() 方法會在內(nèi)部有效地創(chuàng)建第二個 Runnable 對象。)

  線程間的協(xié)作

  應(yīng)在語言中加入更多的功能以支持線程間的相互通信。目前,PipedInputStream 和 PipedOutputStream 類可用于這個目的。但是對于大多數(shù)應(yīng)用程序,它們太弱了。我建議向 Thread 類加入下列函數(shù): 增加一個 wait_for_start() 方法,它通常處于阻塞狀態(tài),直到一個線程的 run() 方法啟動。(如果等待的線程在調(diào)用 run 之前被釋放,這沒有什么問題)。用這種方法,一個線程可以創(chuàng)建一個或多個輔助線程,并保證在創(chuàng)建線程繼續(xù)執(zhí)行操作之前,這些輔助線程會處于運行狀態(tài)。 (向 Object 類)增加 $send (Object o) 和 Object=$receive() 方法,它們將使用一個內(nèi)部阻斷隊列在線程之間傳送對象。阻斷隊列應(yīng)作為第一個 $send() 調(diào)用的副產(chǎn)品被自動創(chuàng)建。 $send() 調(diào)用會把對象加入隊列。 $receive() 調(diào)用通常處于阻塞狀態(tài),直到有一個對象被加入隊列,然后它返回此對象。這種方法中的變量應(yīng)支持設(shè)定入隊和出隊的操作超時能力: $send (Object o, long timeout) 和 $receive (long timeout)。

   對于讀寫鎖的內(nèi)部支持

  讀寫鎖的概念應(yīng)內(nèi)置到 Java 編程語言中。讀寫器鎖在“Taming Java Threads ”(和其它地方)中有詳細(xì)討論,概括地說:一個讀寫鎖支持多個線程同時訪問一個對象,但是在同一時刻只有一個線程可以修改此對象,并且在訪問進行時不能修改。

  對于一個對象,應(yīng)該只有在$writing 塊中沒有線程時,才支持多個線程進入 $reading 塊。在進行讀操作時,一個試圖進入 $writing 塊的線程會被阻斷,直到讀線程退出 $reading 塊。 當(dāng)有其它線程處于 $writing 塊時,試圖進入 $reading 或 $writing 塊的線程會被阻斷,直到此寫線程退出 $writing 塊。

  如果讀和寫線程都在等待,缺省情況下,讀線程會首先進行。但是,可以使用$writer_priority 屬性修改類的定義來改變這種缺省方式。

  訪問部分創(chuàng)建的對象應(yīng)是非法的

  當(dāng)前情況下,JLS 允許訪問部分創(chuàng)建的對象。例如,在一個構(gòu)造函數(shù)中創(chuàng)建的線程可以訪問正被創(chuàng)建的對象,既使此對象沒有完全被創(chuàng)建。

  設(shè)置x 為 -1 的線程可以和設(shè)置 x 為 0 的線程同時進行。所以,此時 x 的值無法預(yù)測。

  對此問題的一個解決方法是,在構(gòu)造函數(shù)沒有返回之前,對于在此構(gòu)造函數(shù)中創(chuàng)建的線程,既使它的優(yōu)先級比調(diào)用new 的線程高,也要禁止運行它的 run() 方法。

  這就是說,在構(gòu)造函數(shù)返回之前,start() 請求必須被推遲。

  另外,Java 編程語言應(yīng)可允許構(gòu)造函數(shù)的同步。換句話說,下面的代碼(在當(dāng)前情況下是非法的)會象預(yù)期的那樣工作:

  我認(rèn)為第一種方法比第二種更簡潔,但實現(xiàn)起來更為困難。

  volatile關(guān)鍵字應(yīng)象預(yù)期的那樣工作

  JLS 要求保留對于 volatile 操作的請求。大多數(shù) Java 虛擬機都簡單地忽略了這部分內(nèi)容,這是不應(yīng)該的。在多處理器的情況下,許多主機都出現(xiàn)了這種問題,但是它本應(yīng)由 JLS 加以解決的。如果您對這方面感興趣,馬里蘭大學(xué)的 Bill Pugh 正在致力于這項工作(請參閱參考資料 )。

  訪問的問題

  如果缺少良好的訪問控制,會使線程編程非常困難。大多數(shù)情況下,如果能保證線程只從同步子系統(tǒng)中調(diào)用,不必考慮線程安全(threadsafe)問題。我建議對 Java 編程語言的訪問權(quán)限概念做如下限制;應(yīng)精確使用 package 關(guān)鍵字來限制包訪問權(quán)。我認(rèn)為當(dāng)缺省行為的存在是任何一種計算機語言的一個瑕疵,我對現(xiàn)在存在這種缺省權(quán)限感到很迷惑(而且這種缺省是“包(package)”級別的而不是“私有(private)”)。在其它方面,Java 編程語言都不提供等同的缺省關(guān)鍵字。雖然使用顯式的 package 的限定詞會破壞現(xiàn)有代碼,但是它將使代碼的可讀性更強,并能消除整個類的潛在錯誤 (例如,如果訪問權(quán)是由于錯誤被忽略,而不是被故意忽略)。 重新引入 private protected ,它的功能應(yīng)和現(xiàn)在的 protected 一樣,但是不應(yīng)允許包級別的訪問。 允許 private private 語法指定“實現(xiàn)的訪問”對于所有外部對象是私有的,甚至是當(dāng)前對象是的同一個類的。對于“.”左邊的唯一引用(隱式或顯式)應(yīng)是 this 。 擴展 public 的語法,以授權(quán)它可制定特定類的訪問。例如,下面的代碼應(yīng)允許 Fred 類的對象可調(diào)用 some_method() ,但是對其它類的對象,這個方法應(yīng)是私有的。

  這種建議不同于 C++ 的 "friend" 機制。 在 "friend" 機制中,它授權(quán)一個類訪問另一個類的所有 私有部分。在這里,我建議對有限的方法集合進行嚴(yán)格控制的訪問。用這種方法,一個類可以為另一個類定義一個接口,而這個接口對系統(tǒng)的其余類是不可見的。

  除非域引用的是真正不變(immutable)的對象或static final 基本類型,否則所有域的定義應(yīng)是 private 。對于一個類中域的直接訪問違反了 OO 設(shè)計的兩個基本規(guī)則:抽象和封裝。從線程的觀點來看,允許直接訪問域只使對它進行非同步訪問更容易一些。

  增加$property 關(guān)鍵字。帶有此關(guān)鍵字的對象可被一個“bean 盒”應(yīng)用程序訪問,這個程序使用在 Class 類中定義的反射操作(introspection) API,否則與 private private 同效。 $property 屬性可用在域和方法,這樣現(xiàn)有的 JavaBean getter/setter 方法可以很容易地被定義為屬性。

  不變性(immutability)

  由于對不變對象的訪問不需要同步,所以在多線程條件下,不變的概念(一個對象的值在創(chuàng)建后不可更改)是無價的。Java 編程言語中,對于不變性的實現(xiàn)不夠嚴(yán)格,有兩個原因:對于一個不變對象,在其被未完全創(chuàng)建之前,可以對它進行訪問。這種訪問對于某些域可以產(chǎn)生不正確的值。 對于恒定 (類的所有域都是 final) 的定義太松散。對于由 final 引用指定的對象,雖然引用本身不能改變,但是對象本身可以改變狀態(tài)。

  第一個問題可以解決,不允許線程在構(gòu)造函數(shù)中開始執(zhí)行 (或者在構(gòu)造函數(shù)返回之前不能執(zhí)行開始請求)。

  對于第二個問題,通過限定final 修飾符指向恒定對象,可以解決此問題。這就是說,對于一個對象,只有所有的域是 final,并且所有引用的對象的域也都是 final,此對象才真正是恒定的。為了不打破現(xiàn)有代碼,這個定義可以使用編譯器加強,即只有一個類被顯式標(biāo)為不變時,此類才是不變類。

  有了$immutable 修飾符后,在域定義中的 final 修飾符是可選的。

  最后,當(dāng)使用內(nèi)部類(inner class)后,在 Java 編譯器中的一個錯誤使它無法可靠地創(chuàng)建不變對象。

  既使空的 final 在每個構(gòu)造函數(shù)中都有初始化,還是會出現(xiàn)這個錯誤信息。自從在 1.1 版本中引入內(nèi)部類后,編譯器中一直有這個錯誤。在此版本中(三年以后),這個錯誤依然存在?,F(xiàn)在,該是改正這個錯誤的時候了。

  對于類級域的實例級訪問

  除了訪問權(quán)限外,還有一個問題,即類級(靜態(tài))方法和實例(非靜態(tài))方法都能直接訪問類級(靜態(tài))域。這種訪問是非常危險的,因為實例方法的同步不會獲取類級的鎖,所以一個synchronized static 方法和一個 synchronized 方法還是能同時訪問類的域。改正此問題的一個明顯的方法是,要求在實例方法中只有使用 static 訪問方法才能訪問非不變類的 static 域。當(dāng)然,這種要求需要編譯器和運行時間檢查。

  由于f() 和 g() 可以并行運行,所以它們能同時改變 x 的值(產(chǎn)生不定的結(jié)果)。請記住,這里有兩個鎖: static 方法要求屬于 Class 對象的鎖,而非靜態(tài)方法要求屬于此類實例的鎖。

  或則,編譯器應(yīng)獲得讀/寫鎖的使用:

  另外一種方法是(這也是一種理想的 方法)-- 編譯器應(yīng) 自動 使用一個讀/寫鎖來同步訪問非不變 static 域,這樣,程序員就不必?fù)?dān)心這個問題。

  后臺線程的突然結(jié)束

  當(dāng)所有的非后臺線程終止后,后臺線程都被突然結(jié)束。當(dāng)后臺線程創(chuàng)建了一些全局資源(例如一個數(shù)據(jù)庫連接或一個臨時文件),而后臺線程結(jié)束時這些資源沒有被關(guān)閉或刪除就會導(dǎo)致問題。

  對于這個問題,我建議制定規(guī)則,使 Java 虛擬機在下列情況下不關(guān)閉應(yīng)用程序:有任何非后臺線程正在運行,或者: 有任何后臺線程正在執(zhí)行一個 synchronized 方法或 synchronized 代碼塊。

  后臺線程在它執(zhí)行完synchronized 塊或 synchronized 方法后可被立即關(guān)閉。

  重新引入stop() 、 suspend() 和 resume() 關(guān)鍵字

  由于實用原因這也許不可行,但是我希望不要廢除stop() (在 Thread 和 ThreadGroup 中)。但是,我會改變 stop() 的語義,使得調(diào)用它時不會破壞已有代碼。但是,關(guān)于 stop() 的問題,請記住,當(dāng)線程終止后, stop() 將釋放所有鎖,這樣可能潛在地使正在此對象上工作的線程進入一種不穩(wěn)定(局部修改)的狀態(tài)。由于停止的線程已釋放它在此對象上的所有鎖,所以這些對象無法再被訪問。

  對于這個問題,可以重新定義stop() 的行為,使線程只有在不占有任何鎖時才立即終止。如果它占據(jù)著鎖,我建議在此線程釋放最后一個鎖后才終止它??梢允褂靡粋€和拋出異常相似的機制來實現(xiàn)此行為。被停止線程應(yīng)設(shè)置一個標(biāo)志,并且當(dāng)退出所有同步塊時立即測試此標(biāo)志。如果設(shè)置了此標(biāo)志,就拋出一個隱式的異常,但是此異常應(yīng)不再能被捕捉并且當(dāng)線程結(jié)束時不會產(chǎn)生任何輸出。注意,微軟的 NT 操作系統(tǒng)不能很好地處理一個外部指示的突然停止(abrupt)。(它不把 stop 消息通知動態(tài)連接庫,所以可能導(dǎo)致系統(tǒng)級的資源漏洞。)這就是我建議使用類似異常的方法簡單地導(dǎo)致 run() 返回的原因。

  與這種和異常類似的處理方法帶來的實際問題是,你必需在每個synchronized 塊后都插入代碼來測試“stopped”標(biāo)志。并且這種附加的代碼會降低系統(tǒng)性能并增加代碼長度。我想到的另外一個辦法是使 stop() 實現(xiàn)一個“延遲的(lazy)”停止,在這種情況下,在下次調(diào)用 wait() 或 yield() 時才終止。我還想向 Thread 中加入一個 isStopped() 和 stopped() 方法(此時, Thread 將像 isInterrupted() 和 interrupted() 一樣工作,但是會檢測 “stop-requested”的狀態(tài))。這種方法不向第一種那樣通用,但是可行并且不會產(chǎn)生過載。

  應(yīng)把suspend() 和 resume() 方法放回到 Java 編程語言中,它們是很有用的,我不想被當(dāng)成是幼兒園的小孩。由于它們可能產(chǎn)生潛在的危險(當(dāng)被掛起時,一個線程可以占據(jù)一個鎖)而去掉它們是沒有道理的。請讓我自己來決定是否使用它們。如果接收的線程正占據(jù)著鎖,Sun 公司應(yīng)該把它們作為調(diào)用 suspend() 的一個運行時間異常處理(run-time exception);或者更好的方法是,延遲實際的掛起過程,直到線程釋放所有的鎖。

  被阻斷的 I/O 應(yīng)正確工作

  應(yīng)該能打斷任何被阻斷的操作,而不是只讓它們wait() 和 sleep() 。我在“ Taming Java Threads ”的第二章中的 socket 部分討論了此問題。但是現(xiàn)在,對于一個被阻斷的 socket 上的 I/O 操作,打斷它的唯一辦法是關(guān)閉這個 socket,而沒有辦法打斷一個被阻斷的文件 I/O 操作。例如,一旦開始一個讀請求并且進入阻斷狀態(tài)后,除非到它實際讀出一些東西,否則線程一直出于阻斷狀態(tài)。既使關(guān)掉文件句柄也不能打斷讀操作。

  還有,程序應(yīng)支持 I/O 操作的超時。所有可能出現(xiàn)阻斷操作的對象(例如 InputStream 對象)也都應(yīng)支持這種方法。

  這和 Socket 類的setSoTimeout(time) 方法是等價的。同樣地,應(yīng)該支持把超時作為參數(shù)傳遞到阻斷的調(diào)用。

  ThreadGroup類

  ThreadGroup應(yīng)該實現(xiàn) Thread 中能夠改變線程狀態(tài)的所有方法。我特別想讓它實現(xiàn) join() 方法,這樣我就可等待組中的所有線程的終止。

  總結(jié)

  以上是我的建議。就像我在標(biāo)題中所說的那樣,如果我是國王...(哎)。我希望這些改變(或其它等同的方法)最終能被引入 Java 語言中。我確實認(rèn)為 Java 語言是一種偉大的編程語言;但是我也認(rèn)為 Java 的線程模型設(shè)計得還不夠完善,這是一件很可惜的事情。但是,Java 編程語言正在演變,所以還有可提高的前景。

您可能感興趣的文章:
  • 簡單了解Java Netty Reactor三種線程模型
  • java自定義線程模型處理方法分享
  • RxJava2 線程調(diào)度的方法
  • Java線程調(diào)度之線程休眠用法分析
  • 詳解Java中的線程模型與線程調(diào)度

標(biāo)簽:亳州 紅河 拉薩 大興安嶺 武威 鄭州 馬鞍山 岳陽

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Java線程模型缺陷》,本文關(guān)鍵詞  Java,線程,模型,缺陷,Java,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Java線程模型缺陷》相關(guān)的同類信息!
  • 本頁收集關(guān)于Java線程模型缺陷的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    丁香花免费高清完整在线播放| 这里只有精品丝袜| 美女的尿口免费视频| 欧美成人精品一区二区免费看片| 日韩欧美精品一区二区| eeuss影院www在线观看手机| 爱情岛论坛亚洲首页入口章节| 可以在线观看的av网站| 暖暖成人免费视频| 久久蜜桃av一区精品变态类天堂| 中文字幕一二三四| 亚洲成人动漫精品| 国产麻豆高清视频在线第一页| 免费久久久久久| jizzjizzjizz在线观看| 精品免费视频一区二区| 国产一区二区在线视频播放| 夜夜躁狠狠躁日日躁2021日韩| 欧美人善zozσ性伦交| 久久丝袜视频| 久久久久亚洲av片无码v| 亚洲色图欧美另类| 欧美亚男人的天堂| 成年人网站在线| 欧美极品第一页| 美女胸又www又黄的网站| 色播色播色播色播色播在线| 久久久国产精品x99av| 日本中文字幕视频在线| 成人3d漫画免费无遮挡软件| 一本色道久久综合亚洲精品图片| 嫩草嫩草嫩草| 黄色成人在线免费| 亚洲国产精品久久久久蝴蝶传媒| 无码人妻丰满熟妇区毛片蜜桃精品| 国产性猛交普通话对白| 日本少妇激情视频| 日韩欧美精品综合| 精品国产1区2区3区| 三级不卡在线观看| 中文字幕乱伦视频| 日韩国产欧美一区二区| 天堂av资源网| 色8久久人人97超碰香蕉987| 久久久久九九九| 狠狠激情五月综合婷婷俺| 亚洲欧洲国产精品| av小片在线| 国产成人精品网| 性少妇videosexfreexxx片| 久久永久免费视频| 在线免费观看麻豆| se视频在线观看| 免费看日本黄色| 亚洲欧美日韩天堂| 日批视频免费在线观看| 日韩伦理一区二区三区av在线| 亚洲美女15p| 欧美人xxxxx| 一区二区三区蜜桃| 精品亚洲国内自在自线福利| 欧美成人一区二区| 亚洲人午夜精品| 国产免费黄色小视频| 九义人在线观看完整免费版电视剧| 亚洲色图美腿丝袜| 欧美三日本三级三级在线播放| 精品国产人成亚洲区| 亚洲美女激情视频| 欧美成人久久久免费播放| 亚洲狠狠婷婷综合久久久| 在线免费观看国产精品| 日韩av在线电影网| 91麻豆国产精品| www.一区二区| 国产精品69久久久久孕妇欧美| 色多多在线观看| 人人草在线视频| 高潮在线视频| 交100部在线观看| 精品网站999| 亚洲黄色尤物视频| 亚洲wwww| 国产又爽又黄网站亚洲视频123| 亚洲一区二区国产| 欧美久久久久久久久久久久久久| 日韩一区二区三区在线免费观看| 国产麻豆一区二区三区精品| 国产精品-区区久久久狼| 日本免费久久高清视频| 亚洲最大成人| aaaa一级片| 色综合一本到久久亚洲91| 伊人久久大香线蕉成人综合网| 中文字幕乱码免费| 亚洲电影成人av99爱色| 欧美一级电影久久| 亚洲色图欧美色| 亚洲国产精品悠悠久久琪琪| 激情视频在线播放| 粉嫩tv在线播放| 国产精品久久久久久亚洲av| av影片在线| 中文字幕777| 你懂的网站在线观看网址| 又粗又大的机巴好爽欧美| 欧美三日本三级少妇三99| 九九精品视频在线观看| 精品国产一区二区三区久久狼5月| 亚洲 国产 欧美 日韩| 青青草原国产免费| 国产福利精品在线| 久草精品视频| www成人在线观看| 影音先锋另类| 国产一区在线电影| 亚洲精品乱码久久久久久久久久久久| 精品网站999www| 精品无码一区二区三区| yourporn在线观看中文站| 亚欧洲精品在线视频| 亚洲综合色网| 濑亚美莉大战黑人中文字幕| 天天操综合520| 在线综合视频播放| 国产传媒一区二区三区| 欧美日韩不卡在线视频| 久久久成人精品| 国产视频一二三| 青娱乐91视频| 欧美麻豆精品久久久久久| 91视频福利网| 国语对白做受69| 欧美成人aaa| 国产天堂视频| 亚洲精品无码专区| 99久久国产综合精品成人影院| 免费观看一区二区三区| 91成人在线精品| 国产精品免费观看久久| 欧洲国产伦久久久久久久| 精品久久久国产| 国产裸体舞一区二区三区| 久久精品xxxxx| 日韩一级片一区二区| 国产精品久久久久桃色tv| 欧美精品一区二区三区蜜臀| 欧美日韩国产经典色站一区二区三区| 欧美日韩影院| 久久免费成人精品视频| 亚洲91久久| jazzjazz国产精品麻豆| 看亚洲a级一级毛片| 久久人人爽人人爽人人片亚洲| 亚洲欧美日韩精品一区二区| 国产日韩欧美在线看| 国产精品乱码久久久| 亚洲精品一二三| 欧美女激情福利| 97人妻精品一区二区三区免| 欧美性xxxx极品hd满灌| 亚洲视频播放| 成人久久18免费网站漫画| 亚洲美女搞黄| 国产鲁鲁视频在线观看特色| 亚洲视频手机在线观看| 在线黄色国产视频| 中文字幕 自拍偷拍| 尤物在线视频| 男生女生差差差的视频在线观看| 在线观看毛片视频| 欧美精品久久久| 91原创国产| 天堂在线中文在线| 综合av色偷偷网| 国内精品女同女同一区二区三区| 久久精品成人欧美大片免费| 亚洲另类黄色| 国产av自拍一区| 色网站在线视频| 91香蕉视频在线下载| 国产色综合久久| 欧洲有码在线视频| 伦av综合一区| 99久久久国产精品美女| 久久久成人免费视频| 一区二区在线观看视频| 亚洲精品永久视频| 美女一区二区视频| 亚洲国产精品va在线看黑人| 依依成人综合网| 亚洲熟女综合色一区二区三区| 风间由美一区二区三区| 久久青草欧美一区二区三区| 国产高清不卡一区二区| 羞羞视频在线观看| 91丨porny丨最新| 四虎精品免费视频| 好吊妞国产欧美日韩免费观看网站| 日本不卡二三区| 91啪九色porn原创视频在线观看| 成人在线观看小视频| 2022中文字幕| 久久国产精品色av免费看| 91精品国产综合久久香蕉最新版| 色撸撸在线观看| 欧美性大战久久久久xxx| 亚洲国产精品区| 精品国产一区二区三区久久久| 奇米影视在线99精品| 99久久夜色精品国产亚洲狼| 在线精品观看国产| 狠狠色综合色区| 精品伊人久久久久7777人| 韩日精品一区二区| 亚洲精品网站在线观看| 日韩成人av一区二区| 一本大道东京热无码aⅴ| 日韩av免费| 91精品国产91久久久久久久久| 久热在线观看视频| 欧美极品在线视频| 欧美激情一区三区| 三级影片在线观看欧美日韩一区二区| 国产综合 伊人色| 在线综合亚洲欧美在线视频| 欧美日韩一区二区三区| 久久躁日日躁aaaaxxxx| 亚洲女与黑人做爰| 欧美猛男男办公室激情| 亚洲一区在线观看免费| 国产91在线看| 四虎1515hh.com| 久久99国内| 久久久一本精品99久久精品66| 国产偷国产偷亚洲高清97cao| 色视频在线观看| 中文字幕乱码日本亚洲一区二区| 亚洲免费成人| 特黄视频在线观看| 999免费视频| 国产毛片久久久久| av中文在线资源| 国产精品扒开做爽爽爽的视频| 成人精品久久av网站| 久久99国产精品一区| 欧美电影免费提供在线观看| 久久亚洲国产精品| 中文字幕日韩精品在线| 黄色小视频免费观看| 黄色成人在线播放| 国产精品另类一区| 97se亚洲国产综合自在线观| 天堂在线资源视频| 多男操一女视频| www.午夜色大片| 色乱码一区二区三在线看| 国产女主播一区| 一级黄色免费视频| 免费在线成人网| 亚洲高清视频的网址| 日韩欧美国产三级电影视频| 99亚洲男女激情在线观看| 中文日产幕无线码一区二区| 成人免费公开视频| 欧美极品欧美精品欧美| 成人午夜激情影院| sdde在线播放一区二区| 电影中文字幕一区二区| 国产亚洲精品bt天堂精选| 日韩精品在线第一页| 国产性猛交普通话对白| 少妇免费视频| free性欧洲69| 成人在线免费观看视频网站| h片在线观看视频免费| 国产精品久久久久久久成人午夜| 免费视频中文字幕| 国产小视频免费| 欧美日韩精品亚洲精品| 成人在线视频网址| 成人黄色图片网站| 欧美 日韩 国产在线| 日韩av影视大全| 日本免费精品| 一区二区三区在线观看国产| 亚洲国产日韩欧美一区二区三区| 91麻豆高清视频| 奇米影视888狠狠狠777不卡| 蜜桃视频第一区免费观看| 激情av在线播放| 成年人视频在线网站| 国产无码精品在线播放| 免费观看91视频大全| 日本成人xxx| 色综合桃花网| 中文在线a天堂| 亚洲黄色成人| www在线视频| 日韩你懂的在线播放| 尤物视频一区二区| 五月婷婷综合网| 激情文学综合| 在线看a视频| 日韩免费观看在线观看| 天天做夜夜爱爱爱| 伊人久久亚洲综合| 91精品国自产在线观看| 欧美刺激性大交免费视频| 韩剧1988免费观看全集| 丰满白嫩尤物一区二区| 91国模少妇一区二区三区| 久久九九99| 五月激情六月婷婷| 欧美影院一区| 久久久久久久国产精品| 午夜在线不卡| 日本不卡一区二区三区在线观看| 超碰成人免费| 中文字幕永久视频| 日本麻豆一区二区三区视频| 亚洲人亚洲人成电影网站色| 99久久精品日本一区二区免费| 91亚洲精品久久久蜜桃借种| 麻豆精品一区二区三区| 日本精品免费一区二区三区| 国产ts人妖一区二区| 日韩高清有码在线|