Java語言程序設(shè)計第08章.ppt_第1頁
Java語言程序設(shè)計第08章.ppt_第2頁
Java語言程序設(shè)計第08章.ppt_第3頁
Java語言程序設(shè)計第08章.ppt_第4頁
Java語言程序設(shè)計第08章.ppt_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第8章 多線程編程,支持多線程編程是Java語言的又一大特色。多線程是相對于進程或單線程而言的,它具有并發(fā)性、執(zhí)行效率高的特點。本章將對Java中的多線程編程作初步介紹。,8.1 多線程編程概述 8.2 線程的創(chuàng)建 8.3 線程的優(yōu)先級 8.4 線程同步 8.5 線程間通信 8.6 線程的控制,Return,8.1 多線程編程概述,本節(jié)介紹多線程編程的基礎(chǔ)知識,包括多線程的基本概念、Java的線程模型(線程優(yōu)先級、同步性、消息傳遞)等方面的內(nèi)容。,8.1.1 什么是多線程 8.1.2 Java線程模型,Return,8.1.1 什么是多線程,同其他大多數(shù)編程語言不同,Java內(nèi)置支持多線程編程(multithreaded programming)。多線程程序包含兩條或兩條以上并發(fā)運行的部分,把程序中每個這樣的部分都叫作一個線程(thread)。每個線程都有獨立的執(zhí)行路徑,因此多線程是多任務(wù)處理的一種特殊形式。 讀者可能知道多任務(wù)處理,它實際上被所有的現(xiàn)代操作系統(tǒng)所支持。然而,多任務(wù)處理有兩種截然不同的類型:基于進程的和基于線程的。搞清楚兩者的區(qū)別是很重要的。對大多數(shù)讀者來說,基于進程的多任務(wù)處理是更熟悉的形式。進程(process)本質(zhì)上是一個執(zhí)行的程序。因此基于進程的多任務(wù)處理的特點是允許你的計算機同時運行兩個或更多的程序。舉例來說,基于進程的多任務(wù)處理使你在運用文本編輯器的時候可以同時運行Java編譯器。在基于進程的多任務(wù)處理中,程序是調(diào)度程序所分派的最小代碼單位。 而在基于線程(thread-based)的多任務(wù)處理環(huán)境中,線程是最小的執(zhí)行單位。這意味著一個程序可以同時執(zhí)行兩個或者多個任務(wù)的功能。例如,一個文本編輯器可以在打印的同時格式化文本。所以,多進程程序處理“大圖片”,而多線程程序處理細節(jié)問題。,Return,多線程程序比多進程程序需要更少的管理費用。進程是重量級的任務(wù),需要分配給它們獨立的地址空間。進程間通信是昂貴和受限的。進程間的轉(zhuǎn)換也是很需要花費的。另一方面,線程是輕量級的選手。它們共享相同的地址空間并且共同分享同一個進程。線程間通信是便宜的,線程間的轉(zhuǎn)換也是低成本的。當Java程序使用多進程任務(wù)處理環(huán)境時,多進程程序不受Java的控制,而多線程則受Java控制。 多線程可幫助你編寫出CPU最大利用率的高效程序,使得空閑時間保持最低。這對Java運行的交互式的網(wǎng)絡(luò)互連環(huán)境是至關(guān)重要的,因為空閑時間是公共的。例如,網(wǎng)絡(luò)的數(shù)據(jù)傳輸速率遠低于計算機處理能力,而本地文件系統(tǒng)資源的讀寫速度也遠低于CPU的處理能力。當然,用戶輸入也比計算機慢很多。在傳統(tǒng)的單線程環(huán)境中,程序必須等待每一個這樣的任務(wù)完成以后才能執(zhí)行下一步盡管CPU有很多空閑時間。多線程使你能夠獲得并充分利用這些空閑時間。,8.1.2 Java線程模型,Java運行系統(tǒng)在很多方面依賴于線程,所有的類庫設(shè)計都考慮到多線程。實際上,Java使用線程來使整個環(huán)境異步。這有利于通過防止CPU循環(huán)的浪費來減少無效部分。 為更好地理解多線程環(huán)境的優(yōu)勢,我們可以將它與它的對照物相比較。單線程系統(tǒng)的處理途徑是使用一種叫作輪詢的事件循環(huán)方法。在該模型中,單線程控制在一無限循環(huán)中運行,輪詢一個事件序列來決定下一步做什么。一旦輪詢裝置返回信號表明已準備好讀取網(wǎng)絡(luò)文件,事件循環(huán)調(diào)度控制管理到適當?shù)氖录幚沓绦?。直到事件處理程序返回,系統(tǒng)中沒有其他事件發(fā)生。這就浪費了CPU時間。這導(dǎo)致了程序的一部分獨占了系統(tǒng),阻止了其他事件的執(zhí)行??偟膩碚f,單線程環(huán)境,當一個線程因為等待資源時阻塞(block,掛起執(zhí)行),整個程序停止運行。,Java多線程的優(yōu)點就在于取消了主循環(huán)/輪詢機制。一個線程可以暫停而不影響程序的其他部分。例如,當一個線程從網(wǎng)絡(luò)讀取數(shù)據(jù)或等待用戶輸入時產(chǎn)生的空閑時間可以被利用到其他地方。多線程允許活的循環(huán)在每一幀間隙中沉睡一秒而不暫停整個系統(tǒng)。在Java程序中出現(xiàn)線程阻塞,僅有一個線程暫停,其他線程繼續(xù)運行。 線程存在多種狀態(tài)。線程可以正在運行(running),只要獲得了CPU時間它就可以運行;運行的線程可以被掛起(suspend),并臨時中斷它的執(zhí)行;一個掛起的線程可以被恢復(fù)(resume),允許它從停止的地方繼續(xù)運行;一個線程可以在等待資源時被阻塞(block);在任何時候,線程可以被終止(terminate),這將立即中斷運行。一旦終止,線程不能被恢復(fù)。線程的各狀態(tài)間關(guān)系見教材P190頁圖8-1所示。,下面簡要介紹與Java線程相關(guān)的幾個概念,Java給每個線程安排優(yōu)先級以決定與其他線程比較時該如何對待該線程。線程優(yōu)先級是詳細說明線程間優(yōu)先關(guān)系的整數(shù)。作為絕對值,優(yōu)先級是毫無意義的;當只有一個線程時,優(yōu)先級高的線程并不比優(yōu)先級低的線程運行的快。相反,線程的優(yōu)先級是用來決定何時從一個運行的線程切換到另一個。這叫“上下文轉(zhuǎn)換”(context switch)。決定上下文轉(zhuǎn)換發(fā)生的規(guī)則很簡單: l線程可以自動放棄控制。在I/O未決定的情況下,睡眠或阻塞由明確的讓步來完成。在這種假定下,所有其他的線程被檢測,準備運行的最高優(yōu)先級線程被授予CPU。 l線程可以被高優(yōu)先級的線程搶占。在這種情況下,低優(yōu)先級線程不主動放棄,處理器只是被先占無論它正在干什么處理器被高優(yōu)先級的線程占據(jù)?;旧?,一旦高優(yōu)先級線程要運行,它就執(zhí)行。這叫做有優(yōu)先級的多任務(wù)處理。 當兩個相同優(yōu)先級的線程競爭CPU周期時,情形有一點復(fù)雜。對于Windows這樣的操作系統(tǒng),等優(yōu)先級的線程是在循環(huán)模式下自動劃分時間的。對于其他一些非Windows操作系統(tǒng)而,如Solaris 2.x,等優(yōu)先級線程相對于它們的對等體自動放棄。如果不這樣,其他的線程就不會運行。,1線程優(yōu)先級,2同步性,由于多線程在程序中引入了一個異步行為,故在需要的時候必須有加強同步性的方法。舉例來說,如果你希望兩個線程相互通信并共享一個復(fù)雜的數(shù)據(jù)結(jié)構(gòu),例如鏈表序列,就需要某些方法來確保它們沒有相互沖突。也就是說,你必須防止一個線程寫入數(shù)據(jù)而另一個線程正在讀取鏈表中的數(shù)據(jù)。為此,Java在進程間同步性的老模式基礎(chǔ)上實行了另外的一種方法:管程(monitor)。管程是一種由C.A.R.Hoare首先定義的控制機制。你可以把管程想象成一個僅控制一個線程的小盒子。一旦線程進入管程,所有線程必須等待直到該線程退出了管程。用這種方法,管程可以用來防止共享的資源被多個線程操縱。 很多多線程系統(tǒng)將管程作為程序必須明確的引用和操作的對象。但Java提供一個清晰的解決方案,不提供“Monitor”類;相反,每個對象都擁有自己的隱式管程,當對象的同步方法被調(diào)用時管程自動載入。一旦一個線程包含在一個同步方法中,沒有其他線程可以調(diào)用相同對象的同步方法。這就使你可以編寫非常清晰和簡潔的多線程代碼,因為同步支持是語言內(nèi)置的。,3消息傳遞,當把程序分成若干線程后,就要定義各線程之間的聯(lián)系。用大多數(shù)其他語言規(guī)劃時必須依賴于操作系統(tǒng)來確立線程間通信,這樣當然要增加花費。然而,Java提供了多線程間談話清潔的、低成本的途徑通過調(diào)用所有對象都有的預(yù)先確定的方法。Java的消息傳遞系統(tǒng)允許一個線程進入一個對象的一個同步方法,然后在那里等待,一直等到其他線程明確通知它出來。,Return,Java的多線程系統(tǒng)建立于Thread類、方法以及共伴接口Runnable基礎(chǔ)上。Thread類封裝了線程的執(zhí)行。既然不能直接引用運行著的線程的狀態(tài),就要通過它的代理處理它。于是Thread 實例產(chǎn)生了。為創(chuàng)建一個新的線程,程序中必須擴展Thread 或?qū)崿F(xiàn)Runnable接口。Thread類定義了好幾種方法來幫助管理線程,見教材P192頁表8-1中所列。,4Thread類和Runnable接口,8.2 線程的創(chuàng)建,本節(jié)介紹在Java中如何創(chuàng)建線程。主要內(nèi)容包括主線程、多線程的創(chuàng)建、相關(guān)方法的使用等。,8.2.1 關(guān)于主線程 8.2.2 創(chuàng)建一個線程 8.2.3 創(chuàng)建多線程 8.2.4 使用isAlive()和join(),Return,8.2.1 關(guān)于主線程,當Java程序啟動時,一個線程立刻運行,該線程通常就叫做程序的主線程(main thread),因為它是程序開始時就執(zhí)行的。主線程的重要性主要體現(xiàn)在兩方面: l它是產(chǎn)生其他子線程的線程; l通常它必須最后完成執(zhí)行,因為它執(zhí)行各種關(guān)閉動作。 盡管主線程在程序啟動時自動創(chuàng)建,但它可以由一個Thread對象控制。為此,必須調(diào)用方法currentThread()獲得它的一個引用,currentThread()是Thread類的公有的靜態(tài)成員。它的一般形式如下 static Thread currentThread() 該方法返回一個調(diào)用它的線程的引用。一旦獲得主線程的引用,就可以像控制其他線程那樣控制主線程。 下面我們考察一下教材P192193頁的程序代碼。 在上面的程序中,當前線程(當然是主線程)的引用通過調(diào)用currentThread()獲得,該引用保存在局部變量t中。然后,程序顯示了線程的信息。接著,程序調(diào)用setName()改變線程的內(nèi)部名稱,線程信息又被顯示。然后,一個循環(huán)數(shù)從5開始遞減,每數(shù)一次暫停一秒。暫停是由sleep()方法來完成的,sleep()語句明確規(guī)定延遲時間是1毫秒。請讀者注意循環(huán)外的try/ catch塊。Thread類的sleep()方法可能引發(fā)一個InterruptedException異常,這種情形會在其他線程想要打攪沉睡線程時發(fā)生。本例只是打印了它是否被打斷的消息。在實際的程序中,必須靈活處理此類問題。,Return,8.2.2 創(chuàng)建一個線程,大多數(shù)情況,通過實例化一個Thread對象來創(chuàng)建一個線程。Java定義了兩種方式: l實現(xiàn)Runnable 接口; l以繼承Thread類的方式。,創(chuàng)建線程最簡單的方法就是創(chuàng)建一個實現(xiàn)Runnable 接口的類,Runnable抽象了一個執(zhí)行代碼單元??梢酝ㄟ^實現(xiàn)Runnable接口的方法創(chuàng)建每一個對象的線程。為實現(xiàn) Runnable 接口,一個類僅需實現(xiàn)一個run()的簡單方法,該方法聲明如下: public void run() 在run()中,可以定義代碼來構(gòu)建新的線程。重要的是:run()方法能夠像主線程那樣調(diào)用其他方法,引用其他類,聲明變量。僅有的不同是:run()在程序中確立另一個并發(fā)的線程執(zhí)行入口。當run()返回時,該線程結(jié)束。 在已經(jīng)創(chuàng)建了實現(xiàn)Runnable接口的類以后,需要在類內(nèi)部實例化一個Thread類的對象。Thread 類定義了好幾種構(gòu)造函數(shù)。我們會用到的如下: Thread(Runnable threadOb, String threadName) 在該構(gòu)造函數(shù)中,threadOb是一個實現(xiàn)Runnable接口類的實例。這定義了線程執(zhí)行的起點,新線程的名稱由threadName定義。 建立新的線程后,它并不運行直到調(diào)用其start()方法,該方法在Thread 類中定義。從本質(zhì)上講,start()執(zhí)行的是一個對run()的調(diào)用。start()方法聲明如下: void start( ),下面我們分別對這兩種方法進行介紹:,1實現(xiàn)Runnable接口,2擴展Thread,創(chuàng)建線程的另一個途徑是創(chuàng)建一個新類來擴展Thread類,然后再創(chuàng)建該類的實例。當一個類繼承Thread時,它必須重載run()方法,這個run()方法是新線程的入口。同時,它也必須調(diào)用start()方法去啟動新線程執(zhí)行。,Return,到這里,讀者可能會奇怪為什么Java有兩種創(chuàng)建子線程的方法,哪一種更好呢。所有的問題都歸于一點。Thread類定義了多種方法可以被派生類重載。對于所有的方法,唯一的必須被重載的是run()方法。這當然是實現(xiàn)Runnable接口所需的同樣的方法。很多Java程序員認為類僅在它們被加強或修改時被擴展。因此,如果你不重載Thread的其他方法,最好只實現(xiàn)Runnable 接口,這當然由自己決定。在本章的其他部分,我們應(yīng)用實現(xiàn)Runnable接口的類來創(chuàng)建線程。,3選擇合適的方法,8.2.3 創(chuàng)建多線程,到目前為止,我們僅用到兩個線程:主線程和一個子線程。然而,我們完全可以創(chuàng)建所需的更多線程。例如,教材P197198頁的程序創(chuàng)建了3個子線程。詳細分析該程序。,Return,8.2.4 使用isAlive()和join(),如前所述,我們一般是希望主線程最后結(jié)束。在上面的例子中,這點是通過在main()中調(diào)用sleep()來實現(xiàn)的,經(jīng)過足夠長時間的延遲以確保所有子線程都先于主線程結(jié)束。然而,這并不是一個好的解決方法。因為有時候存在這個問題:一個線程如何知道另一線程已經(jīng)結(jié)束?幸運的是,Thread類提供了解決此問題的有效方法。 有兩種方法可以判定一個線程是否結(jié)束:第一,可以在線程中調(diào)用isAlive()。這種方法由Thread定義,它的一般形式如下 final boolean isAlive() 如果所調(diào)用線程仍在運行,isAlive()方法返回true,如果不是則返回false。 但isAlive()很少用到,等待線程結(jié)束的更常用的方法是調(diào)用join(),描述如下 final void join() throws InterruptedException 該方法等待所調(diào)用線程結(jié)束,該名字來自于要求線程等待直到指定線程參與的概念。join()的附加形式允許給等待指定線程結(jié)束定義一個最大時間。詳細分析教材P199200頁的程序。,Return,8.3 線程的優(yōu)先級,線程優(yōu)先級被線程調(diào)度用來判定何時某個線程允許運行。理論上,優(yōu)先級高的線程比優(yōu)先級低的線程獲得更多的CPU時間。實際上,線程獲得的CPU時間通常由包括優(yōu)先級在內(nèi)的多個因素決定。一個優(yōu)先級高的線程自然比優(yōu)先級低的線程優(yōu)先。 理論上,等優(yōu)先級線程有同等的權(quán)利使用CPU,但你必須小心。需要記住的是,Java是被設(shè)計成能在很多環(huán)境下工作的。不同環(huán)境下實現(xiàn)多任務(wù)處理從本質(zhì)上來看是可能的。為安全起見,等優(yōu)先級線程有時候也受到控制。這保證了所有線程在無優(yōu)先級的操作系統(tǒng)下都有機會運行。實際上,在無優(yōu)先級的環(huán)境下,多數(shù)線程仍然有機會運行,因為很多線程不可避免地會遭遇阻塞,例如等待輸入輸出。遇到這種情形,阻塞的線程掛起,其他線程運行。但是如果你希望多線程執(zhí)行得順利的話,最好不要采用這種方法。同樣,有些類型的任務(wù)是占CPU的。對于這些支配CPU類型的線程,有時你希望能夠支配它們,以便使其他線程可以運行。 設(shè)置線程的優(yōu)先級,用setPriority()方法,該方法也是Thread的成員。它的通常形式為 final void setPriority(int level) 這里,level指定了對所調(diào)用的線程的新的優(yōu)先權(quán)的設(shè)置。Level的值必須在MIN_PRIORITY到MAX_PRIORITY范圍內(nèi)。通常,它們的值分別是1和10。要返回一個線程為默認的優(yōu)先級,指定NORM_PRIORITY,通常值為5。這些優(yōu)先級在Thread中都被定義為final型變量。,Return,8.4 線程同步,當兩個或兩個以上的線程需要共享資源,它們需要某種方法來確定資源在某一刻僅被一個線程占用,達到此目的的過程叫做同步(synchronization)。Java為此提供了獨特的、很有效的支持機制。,8.4.1 使用同步方法 8.4.2 同步語句,Return,8.4.1 使用同步方法,同步的關(guān)鍵是管程(也叫信號量,即semaphore)的概念。管程是一個互斥獨占鎖定的對象,或稱互斥體(mutex)。在給定的時間,僅有一個線程可以獲得管程。當一個線程需要鎖定時,它必須進入管程。所有其他的試圖進入已經(jīng)鎖定的管程的線程必須掛起直到第一個線程退出管程。這些其他的線程被稱為等待管程。 我們可以用兩種方法同步化代碼。通過調(diào)用sleep(),call()方法允許執(zhí)行轉(zhuǎn)換到另一個線程。兩者都包括synchronized關(guān)鍵字的運用。分析教材P204頁的示例。,Return,8.4.2 同步語句,盡管在創(chuàng)建的類的內(nèi)部創(chuàng)建同步方法是獲得同步的簡單和有效的方法,但它并非在任何時候都有效。假設(shè)你想獲得不為多線程訪問設(shè)計的類對象的同步訪問,也就是該類沒有用到synchronized方法。而且,該類不是你自己,而是第三方創(chuàng)建的,就不能獲得它的源代碼。這樣,就不能在相關(guān)方法前加synchronized修飾符。怎樣才能使該類的一個對象同步化呢?解決的方法很簡單:只需將對這個類定義的方法的調(diào)用放入一個synchronized塊內(nèi)就可以了。 下面是synchronized語句的一般形式 synchronized(object) / statements to be synchronized 其中,object是對同步對象的引用。如果你想要同步的只是一個語句,那么不需要花括號。一個同步塊確保對object成員方法的調(diào)用僅在當前線程成功進入object管程后發(fā)生。,Return,8.5 線程間通信,前面的例子無條件地阻塞了其他線程異步訪問某個方法。Java對象中隱式管程的應(yīng)用是很強大的,但是我們可以通過進程間通信達到更微妙的境界,這在Java中是很簡單的。,8.5.1 Java中的線程通訊 8.5.2 關(guān)于死鎖,Return,8.5.1 Java中的線程通訊,多線程通過把任務(wù)分成離散的和合乎邏輯的單元代替了事件循環(huán)程序。線程還有另外一個優(yōu)點:它遠離了輪詢。輪詢通常由重復(fù)監(jiān)測條件的循環(huán)實現(xiàn)。一旦條件成立,就要采取適當?shù)男袆?。這浪費了CPU時間。 為避免輪詢,Java包含了通過wait(),notify()和notifyAll()方法實現(xiàn)的一個進程間通信機制。這些方法在對象中是用final方法實現(xiàn)的,所以所有的類都含有它們。這三個方法僅在synchronized方法中才能被調(diào)用。盡管這些方法從計算機科學(xué)遠景方向上來說具有概念的高度先進性,實際中用起來卻是很簡單的。 wait()告知被調(diào)用的線程放棄管程進入睡眠直到其他線程進入相同管程并且調(diào)用notify()。 notify()恢復(fù)相同對象中第一個調(diào)用wait()的線程。 notifyAll()恢復(fù)相同對象中所有調(diào)用wait()的線程。 這些方法在Object中被聲明,如下所示 final void wait() throws InterruptedException final void notify() final void notifyAll() wait()存在的另外的形式允許你定義等待時間。分析教材P207210頁的程序段。,Return,8.5.2 關(guān)于死鎖,需要避免的與多任務(wù)處理有關(guān)的特殊錯誤類型是死鎖(deadlock)。死鎖發(fā)生在當兩個線程對一對同步對象有循環(huán)依賴關(guān)系時。例如,假定一個線程進入了對象X的管程而另一個線程進入了對象Y的管程。如果X的線程試圖調(diào)用Y的同步方法,它將像預(yù)料的一樣被鎖定。而Y的線程同樣希望調(diào)用X的一些同步方法,線程永遠等待,因為為到達X,必須釋放自己的Y的鎖定以使第一個線程可以完成。死鎖是很難調(diào)試的錯誤,這是因為:第一,通常它極少發(fā)生,只有到兩線程的時間段剛好符合時才能發(fā)生;第二,它可能包含多于兩個的線程和同步對象。也就是說,死鎖在比剛講述的例子有更多復(fù)雜的事件序列的時候可以發(fā)生。 為充分理解死鎖,觀察它的行為是很有用的。教材P211212頁的例子生成了兩個類,A和B,分別有foo()和bar()方法。這兩種方法在調(diào)用其他類的方法前有一個短暫的停頓。主類,名為Deadlock,創(chuàng)建了A和B的實例,然后啟動第二個線程去設(shè)置死鎖環(huán)境。foo()和bar()方法使用sleep()強迫死鎖現(xiàn)象發(fā)生。 程序死鎖,需要按CTRL-C來結(jié)束程序。在PC機上按CTRL-BREAK(或在Solaris下按CTRL-)可以看到全線程和管程緩沖堆。,Return,8.6 線程的控制,本節(jié)討論有關(guān)線程控制的問題,包括線程的掛起、恢復(fù)、終止等方面的問題。,8.6.1 掛起、恢復(fù)和終止線程 8.6.2 Java 2中的線程控制 8.6.3 使用instanceof,Return,8.6.1 掛起、恢復(fù)和終止線程,有時,線程的掛起是很有用的。例如,一個獨立的線程可以用來顯示當日的時間。如果用戶不希望用時鐘,線程被掛起。在任何情形下,掛起線程是很簡單的,一旦掛起,重新啟動線程也是一件簡單的事。 掛起、終止和恢復(fù)線程機制在Java 2和早期版本中有所不同。盡管你運用Java 2的途徑編寫代碼,仍需了解這些操作在早期Java環(huán)境下是如何完成的。例如,也許你需要更新或維護老的代碼,就需要了解為什么Java 2會有這樣的變化。因為這些原因,下面內(nèi)容說明了執(zhí)行線程控制的原始方法,接著是Java 2的方法。 先于Java2的版本(Java 1.1或更早版本),程序用Thread 定義的suspend() 和 resume() 來暫停和再啟動線程。它們的形式如下。 final void suspend() final void resume() Thread類同樣定義了stop()來終止線程,其形式如下: void stop() 一旦線程被終止,它不能被resume() 恢復(fù)繼續(xù)運行。,Return,8.6.2 Java 2中的線程控制,在Java 2中不能使用suspend(),resume()和stop() 方法來控制線程,讀者也許會想那就沒有辦法來停止、恢復(fù)和結(jié)束線程,其實不然。相反,線程必須被設(shè)計成使用run()方法定期檢查來判定線程是否應(yīng)該被掛起,恢復(fù)或終止它自己的執(zhí)行。有代表性的,這由建立一個指示線程狀態(tài)的標志變量來完成。只要該標志設(shè)為“running”,run()方法必須繼續(xù)讓線程執(zhí)行。如果標志設(shè)為“suspend”,線程必須暫停。若設(shè)為“stop”,線程必須終止。當然,編寫這樣的代碼有很多方

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論