亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 0120.htm

?? 關于java的開發文檔
?? HTM
?? 第 1 頁 / 共 5 頁
字號:
<html>

<head>
<title>新時代軟件教程:操作系統 主頁制作 服務器 設計軟件 網絡技術 編程語言 文字編輯</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style>
<!--
body, table {font-size: 9pt; font-family: 宋體}
a {text-decoration:none}
a:hover {color: red;text-decoration:underline}
.1  {background-color: rgb(245,245,245)}
-->
</style>
</head>
<p align="center"><script src="../../1.js"></script></a>
    <p align="center"><big><strong>第14章 多線程</strong></big></p>

<div align="right">---(原著/Bruce Eckel 翻譯/Trans Bot)</div>

<br>
利用對象,可將一個程序分割成相互獨立的區域。我們通常也需要將一個程序轉換成多個獨立運行的子任務。<br>
象這樣的每個子任務都叫作一個“線程”(Thread)。編寫程序時,可將每個線程都想象成獨立運行,而且都有自己的專用CPU。一些基礎機制實際會為我們自動分割CPU的時間。我們通常不必關心這些細節問題,所以多線程的代碼編寫是相當簡便的。<br>
這時理解一些定義對以后的學習狠有幫助。“進程”是指一種“自包容”的運行程序,有自己的地址空間。“多任務”操作系統能同時運行多個進程(程序)——但實際是由于CPU分時機制的作用,使每個進程都能循環獲得自己的CPU時間片。但由于輪換速度非常快,使得所有程序好象是在“同時”運行一樣。“線程”是進程內部單一的一個順序控制流。因此,一個進程可能容納了多個同時執行的線程。<br>
多線程的應用范圍很廣。但在一般情況下,程序的一些部分同特定的事件或資源聯系在一起,同時又不想為它而暫停程序其他部分的執行。這樣一來,就可考慮創建一個線程,令其與那個事件或資源關聯到一起,并讓它獨立于主程序運行。一個很好的例子便是“Quit”或“退出”按鈕——我們并不希望在程序的每一部分代碼中都輪詢這個按鈕,同時又希望該按鈕能及時地作出響應(使程序看起來似乎經常都在輪詢它)。事實上,多線程最主要的一個用途就是構建一個“反應靈敏”的用戶界面。<br>
<br>
14.1 反應靈敏的用戶界面<br>
作為我們的起點,請思考一個需要執行某些CPU密集型計算的程序。由于CPU“全心全意”為那些計算服務,所以對用戶的輸入十分遲鈍,幾乎沒有什么反應。在這里,我們用一個合成的applet/application(程序片/應用程序)來簡單顯示出一個計數器的結果:<br>
<br>
752-753頁程序<br>
<br>
在這個程序中,AWT和程序片代碼都應是大家熟悉的,第13章對此已有很詳細的交待。go()方法正是程序全心全意服務的對待:將當前的count(計數)值置入TextField(文本字段)t,然后使count增值。<br>
go()內的部分無限循環是調用sleep()。sleep()必須同一個Thread(線程)對象關聯到一起,而且似乎每個應用程序都有部分線程同它關聯(事實上,Java本身就是建立在線程基礎上的,肯定有一些線程會伴隨我們寫的應用一起運行)。所以無論我們是否明確使用了線程,都可利用Thread.currentThread()產生由程序使用的當前線程,然后為那個線程調用sleep()。注意,Thread.currentThread()是Thread類的一個靜態方法。<br>
注意sleep()可能“擲”出一個InterruptException(中斷違例)——盡管產生這樣的違例被認為是中止線程的一種“惡意”手段,而且應該盡可能地杜絕這一做法。再次提醒大家,違例是為異常情況而產生的,而不是為了正常的控制流。在這里包含了對一個“睡眠”線程的中斷,以支持未來的一種語言特性。<br>
一旦按下start按鈕,就會調用go()。研究一下go(),你可能會很自然地(就象我一樣)認為它該支持多線程,因為它會進入“睡眠”狀態。也就是說,盡管方法本身“睡著”了,CPU仍然應該忙于監視其他按鈕“按下”事件。但有一個問題,那就是go()是永遠不會返回的,因為它被設計成一個無限循環。這意味著actionPerformed()根本不會返回。由于在第一個按鍵以后便陷入actionPerformed()中,所以程序不能再對其他任何事件進行控制(如果想出來,必須以某種方式“殺死”進程——最簡便的方式就是在控制臺窗口按Ctrl+C鍵)。<br>
這里最基本的問題是go()需要繼續執行自己的操作,而與此同時,它也需要返回,以便actionPerformed()能夠完成,而且用戶界面也能繼續響應用戶的操作。但對象go()這樣的傳統方法來說,它卻不能在繼續的同時將控制權返回給程序的其他部分。這聽起來似乎是一件不可能做到的事情,就象CPU必須同時位于兩個地方一樣,但線程可以解決一切。“線程模型”(以及Java中的編程支持)是一種程序編寫規范,可在單獨一個程序里實現幾個操作的同時進行。根據這一機制,CPU可為每個線程都分配自己的一部分時間。每個線程都“感覺”自己好象擁有整個CPU,但CPU的計算時間實際卻是在所有線程間分攤的。<br>
線程機制多少降低了一些計算效率,但無論程序的設計,資源的均衡,還是用戶操作的方便性,都從中獲得了巨大的利益。綜合考慮,這一機制是非常有價值的。當然,如果本來就安裝了多塊CPU,那么操作系統能夠自行決定為不同的CPU分配哪些線程,程序的總體運行速度也會變得更快(所有這些都要求操作系統以及應用程序的支持)。多線程和多任務是充分發揮多處理機系統能力的一種最有效的方式。<br>
<br>
14.1.1 從線程繼承<br>
為創建一個線程,最簡單的方法就是從Thread類繼承。這個類包含了創建和運行線程所需的一切東西。Thread最重要的方法是run()。但為了使用run(),必須對其進行過載或者覆蓋,使其能充分按自己的吩咐行事。因此,run()屬于那些會與程序中的其他線程“并發”或“同時”執行的代碼。<br>
下面這個例子可創建任意數量的線程,并通過為每個線程分配一個獨一無二的編號(由一個靜態變量產生),從而對不同的線程進行跟蹤。Thread的run()方法在這里得到了覆蓋,每通過一次循環,計數就減1——計數為0時則完成循環(此時一旦返回run(),線程就中止運行)。<br>
<br>
755頁程序<br>
<br>
run()方法幾乎肯定含有某種形式的循環——它們會一直持續到線程不再需要為止。因此,我們必須規定特定的條件,以便中斷并退出這個循環(或者在上述的例子中,簡單地從run()返回即可)。run()通常采用一種無限循環的形式。也就是說,通過阻止外部發出對線程的stop()或者destroy()調用,它會永遠運行下去(直到程序完成)。<br>
在main()中,可看到創建并運行了大量線程。Thread包含了一個特殊的方法,叫作start(),它的作用是對線程進行特殊的初始化,然后調用run()。所以整個步驟包括:調用構建器來構建對象,然后用start()配置線程,再調用run()。如果不調用start()——如果適當的話,可在構建器那樣做——線程便永遠不會啟動。<br>
下面是該程序某一次運行的輸出(注意每次運行都會不同):<br>
<br>
756頁程序<br>
<br>
可注意到這個例子中到處都調用了sleep(),然而輸出結果指出每個線程都獲得了屬于自己的那一部分CPU執行時間。從中可以看出,盡管sleep()依賴一個線程的存在來執行,但卻與允許或禁止線程無關。它只不過是另一個不同的方法而已。<br>
亦可看出線程并不是按它們創建時的順序運行的。事實上,CPU處理一個現有線程集的順序是不確定的——除非我們親自介入,并用Thread的setPriority()方法調整它們的優先級。<br>
main()創建Thread對象時,它并未捕獲任何一個對象的句柄。普通對象對于垃圾收集來說是一種“公平競賽”,但線程卻并非如此。每個線程都會“注冊”自己,所以某處實際存在著對它的一個引用。這樣一來,垃圾收集器便只好對它“瞠目以對”了。<br>
<br>
14.1.2 針對用戶界面的多線程<br>
現在,我們也許能用一個線程解決在Counter1.java中出現的問題。采用的一個技巧便是在一個線程的run()方法中放置“子任務”——亦即位于go()內的循環。一旦用戶按下Start按鈕,線程就會啟動,但馬上結束線程的創建。這樣一來,盡管線程仍在運行,但程序的主要工作卻能得以繼續(等候并響應用戶界面的事件)。下面是具體的代碼:<br>
<br>
757-759頁程序<br>
<br>
現在,Counter2變成了一個相當直接的程序,它的唯一任務就是設置并管理用戶界面。但假若用戶現在按下Start按鈕,卻不會真正調用一個方法。此時不是創建類的一個線程,而是創建SeparateSubTask,然后繼續Counter2事件循環。注意此時會保存SeparateSubTask的句柄,以便我們按下onOff按鈕的時候,能正常地切換位于SeparateSubTask內部的runFlag(運行標志)。隨后那個線程便可啟動(當它看到標志的時候),然后將自己中止(亦可將SeparateSubTask設為一個內部類來達到這一目的)。<br>
SeparateSubTask類是對Thread的一個簡單擴展,它帶有一個構建器(其中保存了Counter2句柄,然后通過調用start()來運行線程)以及一個run()——本質上包含了Counter1.java的go()內的代碼。由于SeparateSubTask知道自己容納了指向一個Counter2的句柄,所以能夠在需要的時候介入,并訪問Counter2的TestField(文本字段)。<br>
按下onOff按鈕,幾乎立即能得到正確的響應。當然,這個響應其實并不是“立即”發生的,它畢竟和那種由“中斷”驅動的系統不同。只有線程擁有CPU的執行時間,并注意到標記已發生改變,計數器才會停止。<br>
<br>
1. 用內部類改善代碼<br>
下面說說題外話,請大家注意一下SeparateSubTask和Counter2類之間發生的結合行為。SeparateSubTask同Counter2“親密”地結合到了一起——它必須持有指向自己“父”Counter2對象的一個句柄,以便自己能回調和操縱它。但兩個類并不是真的合并為單獨一個類(盡管在下一節中,我們會講到Java確實提供了合并它們的方法),因為它們各自做的是不同的事情,而且是在不同的時間創建的。但不管怎樣,它們依然緊密地結合到一起(更準確地說,應該叫“聯合”),所以使程序代碼多少顯得有些笨拙。在這種情況下,一個內部類可以顯著改善代碼的“可讀性”和執行效率:<br>
<br>
759-761頁程序<br>
<br>
這個SeparateSubTask名字不會與前例中的SeparateSubTask沖突——即使它們都在相同的目錄里——因為它已作為一個內部類隱藏起來。大家亦可看到內部類被設為private(私有)屬性,這意味著它的字段和方法都可獲得默認的訪問權限(run()除外,它必須設為public,因為它在基礎類中是公開的)。除Counter2i之外,其他任何方面都不可訪問private內部類。而且由于兩個類緊密結合在一起,所以很容易放寬它們之間的訪問限制。在SeparateSubTask中,我們可看到invertFlag()方法已被刪去,因為Counter2i現在可以直接訪問runFlag。<br>
此外,注意SeparateSubTask的構建器已得到了簡化——它現在唯一的用外就是啟動線程。Counter2i對象的句柄仍象以前那樣得以捕獲,但不再是通過人工傳遞和引用外部對象來達到這一目的,此時的內部類機制可以自動照料它。在run()中,可看到對t的訪問是直接進行的,似乎它是SeparateSubTask的一個字段。父類中的t字段現在可以變成private,因為SeparateSubTask能在未獲任何特殊許可的前提下自由地訪問它——而且無論如何都該盡可能地把字段變成“私有”屬性,以防來自類外的某種力量不慎地改變它們。<br>
無論在什么時候,只要注意到類相互之間結合得比較緊密,就可考慮利用內部類來改善代碼的編寫與維護。<br>
<br>
14.1.3 用主類合并線程<br>
在上面的例子中,我們看到線程類(Thread)與程序的主類(Main)是分隔開的。這樣做非常合理,而且易于理解。然而,還有另一種方式也是經常要用到的。盡管它不十分明確,但一般都要更簡潔一些(這也解釋了它為什么十分流行)。通過將主程序類變成一個線程,這種形式可將主程序類與線程類合并到一起。由于對一個GUI程序來說,主程序類必須從Frame或Applet繼承,所以必須用一個接口加入額外的功能。這個接口叫作Runnable,其中包含了與Thread一致的基本方法。事實上,Thread也實現了Runnable,它只指出有一個run()方法。<br>
對合并后的程序/線程來說,它的用法不是十分明確。當我們啟動程序時,會創建一個Runnable(可運行的)對象,但不會自行啟動線程。線程的啟動必須明確進行。下面這個程序向我們演示了這一點,它再現了Counter2的功能:<br>
<br>
762-763頁程序1<br>
<br>
現在run()位于類內,但它在init()結束以后仍處在“睡眠”狀態。若按下啟動按鈕,線程便會用多少有些曖昧的表達方式創建(若線程尚不存在):<br>
new Thread(Counter3.this);<br>
若某樣東西有一個Runnable接口,實際只是意味著它有一個run()方法,但不存在與之相關的任何特殊東西——它不具有任何天生的線程處理能力,這與那些從Thread繼承的類是不同的。所以為了從一個Runnable對象產生線程,必須單獨創建一個線程,并為其傳遞Runnable對象;可為其使用一個特殊的構建器,并令其采用一個Runnable作為自己的參數使用。隨后便可為那個線程調用start(),如下所示:<br>

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
蜜桃视频第一区免费观看| 天天影视色香欲综合网老头| 久久久精品tv| 精品人伦一区二区色婷婷| 8v天堂国产在线一区二区| 欧美色图片你懂的| 欧美日韩一本到| 欧美日韩亚州综合| 欧美二区三区91| 欧美酷刑日本凌虐凌虐| 777欧美精品| 日韩免费电影一区| 欧美岛国在线观看| 国产亚洲成年网址在线观看| 久久精品免视看| 中文字幕 久热精品 视频在线| 国产日韩欧美高清| 国产精品灌醉下药二区| 蜜桃传媒麻豆第一区在线观看| 欧美欧美欧美欧美首页| 激情久久久久久久久久久久久久久久| 免费看欧美女人艹b| 久久狠狠亚洲综合| 另类成人小视频在线| 国产精品久久久久久久久果冻传媒 | 日韩欧美国产综合在线一区二区三区| 欧美精品乱人伦久久久久久| 欧美哺乳videos| 国产日韩高清在线| 一区二区三区美女| 青娱乐精品在线视频| 国产在线不卡一区| 99re这里只有精品视频首页| 欧美亚洲一区三区| 欧美日韩和欧美的一区二区| 成人免费毛片高清视频| 91丨porny丨国产| 欧美久久免费观看| 精品成人免费观看| 亚洲欧美偷拍另类a∨色屁股| 亚洲无人区一区| 色婷婷综合中文久久一本| 激情综合网天天干| 成人免费观看视频| 欧美日韩久久久久久| 精品国产91乱码一区二区三区| 中国av一区二区三区| 亚洲午夜一区二区三区| 激情五月婷婷综合网| 91片黄在线观看| 欧美成人video| 亚洲色图制服丝袜| 久久99国产乱子伦精品免费| 99国产精品视频免费观看| 欧美精品色一区二区三区| 国产日产欧美一区二区视频| 亚洲一区自拍偷拍| 国产成人午夜电影网| 欧美日韩在线不卡| 国产精品网友自拍| 免费高清视频精品| 色www精品视频在线观看| 精品国产乱码久久久久久1区2区| 亚洲欧美电影一区二区| 韩国视频一区二区| 欧美人妇做爰xxxⅹ性高电影| 国产欧美视频在线观看| 日韩av电影免费观看高清完整版| 成人app在线| 精品国产乱码91久久久久久网站| 一区二区三区视频在线看| 国产盗摄视频一区二区三区| 9191久久久久久久久久久| 亚洲少妇中出一区| 国产福利精品一区| 日韩欧美一区在线观看| 亚洲国产aⅴ成人精品无吗| 国产九九视频一区二区三区| 91精品国产综合久久精品图片| 亚洲欧美色综合| 成人午夜激情在线| 久久女同精品一区二区| 美女网站视频久久| 欧美日本一道本在线视频| 亚洲男女一区二区三区| 成人免费视频caoporn| 久久精品一区八戒影视| 美国毛片一区二区| 欧美一区二区在线视频| 亚洲国产成人av网| 91福利视频久久久久| 中文字幕日韩一区| 成人性色生活片免费看爆迷你毛片| 精品国产欧美一区二区| 石原莉奈在线亚洲二区| 欧美日韩国产bt| 亚洲动漫第一页| 欧美日韩中文国产| 亚洲一区二区三区在线| 在线亚洲高清视频| 亚洲人123区| 91色乱码一区二区三区| 中文字幕在线不卡一区二区三区| 国产盗摄女厕一区二区三区| 国产欧美日韩精品a在线观看| 久久99久久精品| 欧美成人福利视频| 国产麻豆午夜三级精品| 久久久久久久久久久久久夜| 国产乱一区二区| 国产欧美1区2区3区| 国产成人精品1024| 国产精品午夜电影| av电影在线观看一区| 一区在线观看免费| 91美女片黄在线观看91美女| 尤物在线观看一区| 欧美三片在线视频观看| 天天综合网天天综合色| 91精品国产综合久久久久久 | 成人福利电影精品一区二区在线观看| 久久久久久久久久美女| av电影一区二区| 一区二区三区成人| 欧美日本在线一区| 久久精品国产亚洲一区二区三区| 欧美tickle裸体挠脚心vk| 国产一级精品在线| 国产精品久久毛片| 欧洲一区二区av| 欧美aaaaaa午夜精品| 国产视频视频一区| 色综合久久中文综合久久97| 亚洲bt欧美bt精品| 欧美成人女星排行榜| 国产成人免费视频一区| 亚洲三级久久久| 91精品国产色综合久久ai换脸 | 精油按摩中文字幕久久| 国产欧美久久久精品影院| 91视频一区二区| 亚洲成av人片一区二区梦乃| 欧美一区二区福利在线| 国产91精品欧美| 亚洲精品第1页| 日韩欧美成人一区| 成人一区在线看| 亚洲妇熟xx妇色黄| 国产日韩欧美精品一区| 精品视频123区在线观看| 狠狠久久亚洲欧美| 最新热久久免费视频| 日韩女优视频免费观看| 成人av电影免费观看| 美腿丝袜在线亚洲一区 | av资源网一区| 日本v片在线高清不卡在线观看| 欧美经典三级视频一区二区三区| 欧美性色黄大片手机版| 国产河南妇女毛片精品久久久 | 欧美自拍丝袜亚洲| 激情六月婷婷久久| 亚洲国产aⅴ成人精品无吗| 久久免费的精品国产v∧| 欧美中文字幕一区二区三区| 激情av综合网| 亚洲aⅴ怡春院| 1000部国产精品成人观看| 欧美哺乳videos| 欧美喷水一区二区| 91天堂素人约啪| 国产毛片精品一区| 日韩福利电影在线观看| 亚洲欧洲日本在线| 久久综合九色综合久久久精品综合| 在线一区二区观看| 国产91在线|亚洲| 久久精品国产**网站演员| 亚洲一卡二卡三卡四卡 | 石原莉奈一区二区三区在线观看| 国产精品久久久久久久久免费樱桃| 日韩一区二区三区视频| 欧美亚洲尤物久久| 色综合色狠狠综合色| 国产91精品在线观看| 韩国视频一区二区| 久久精品国产久精国产| 五月天丁香久久| 一区二区三区免费网站| 亚洲欧美中日韩| 国产精品日韩精品欧美在线| 欧美精品一区二区三区在线| 欧美高清视频不卡网| 在线观看日韩电影| 一本高清dvd不卡在线观看| 成人爱爱电影网址| 成人综合婷婷国产精品久久蜜臀| 精品一区二区三区久久久| 天堂蜜桃一区二区三区| 亚洲成人一区在线|