版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、程序是很簡(jiǎn)易的。然而,在編程人員面前,多線程呈現(xiàn)出了一組新的難題,如果沒有被恰當(dāng)?shù)慕鉀Q,將導(dǎo)致意外的行為以及細(xì)微的、難以發(fā)現(xiàn)的錯(cuò)誤。 在本篇文章中,我們針對(duì)這些難題之一:如何中斷一個(gè)正在運(yùn)行的線程。 背景 中斷(Interrupt)一個(gè)線程意味著在該線程完成任務(wù)之前停止其正在進(jìn)行的一切,有效地中止其當(dāng)前的操作。線程是死亡、還是等待新的任務(wù)或是繼續(xù)運(yùn)行至下一步,就取決于這個(gè)程序。雖然初次看來它可能顯得簡(jiǎn)單,但是,你必須進(jìn)行一些預(yù)警以實(shí)現(xiàn)期望的結(jié)果。你最好還是牢記以下的幾點(diǎn)告誡。 首先,忘掉Thread.stop方法。雖然它確實(shí)停止了一個(gè)正在運(yùn)行的線程,然而,這種方法是不安全也是不受提倡的,這意味
2、著,在未來的JAVA版本中,它將不復(fù)存在。 一些輕率的家伙可能被另一種方法Terrupt所迷惑。盡管,其名稱似乎在暗示著什么,然而,這種方法并不會(huì)中斷一個(gè)正在運(yùn)行的線程(待會(huì)將進(jìn)一步說明),正如Listing A中描述的那樣。它創(chuàng)建了一個(gè)線程,并且試圖使用Terrupt方法停止該線程。Thread.sleep()方法的調(diào)用,為線程的初始化和中止提供了充裕的時(shí)間。線程本身并不參與任何有用的操作。 class Example1 extends Thread boolean stop=false; public static void main( String a
3、rgs ) throws Exception Example1 thread = new Example1(); System.out.println( "Starting thread." ); thread.start(); Thread.sleep( 3000 ); System.out.println( "Interrupting thread." ); errupt(); Thread.sleep( 3000 ); System.out.println("Stopping application." );
4、 /System.exit(0); public void run() while(!stop) System.out.println( "Thread is running." ); long time = System.currentTimeMillis(); while(System.currentTimeMillis()-time < 1000) System.out.println("Thread exiting under request." ); 如果你運(yùn)行了Listing A中的代碼,你將在控制臺(tái)看到以下輸出:Starting th
5、read.Thread is running.Thread is running.Thread is running.Interrupting thread.Thread is running.Thread is running.Thread is running.Stopping application.Thread is running.Thread is running.Thread is running. 甚至,在Terrupt()被調(diào)用后,線程仍然繼續(xù)運(yùn)行。真正地中斷一個(gè)線程 中斷線程最好的,最受推薦的方式是,使用共享變量(shared variable)發(fā)出信號(hào),
6、告訴線程必須停止正在運(yùn)行的任務(wù)。線程必須周期性的核查這一變量(尤其在冗余操作期間),然后有秩序地中止任務(wù)。Listing B描述了這一方式。Listing Bclass Example2 extends Thread volatile boolean stop = false; public static void main( String args ) throws Exception Example2 thread = new Example2(); System.out.println( "Starting thread." ); thread.start(); Th
7、read.sleep( 3000 ); System.out.println( "Asking thread to stop." ); thread.stop = true; Thread.sleep( 3000 ); System.out.println( "Stopping application." ); /System.exit( 0 ); public void run() while ( !stop ) System.out.println( "Thread is running." ); long time = Syst
8、em.currentTimeMillis(); while ( (System.currentTimeMillis()-time < 1000) && (!stop) ) System.out.println( "Thread exiting under request." ); 運(yùn)行Listing B中的代碼將產(chǎn)生如下輸出(注意線程是如何有秩序的退出的)Starting thread.Thread is running.Thread is running.Thread is running.Asking thread to stop.Thread e
9、xiting under request.Stopping application. 雖然該方法要求一些編碼,但并不難實(shí)現(xiàn)。同時(shí),它給予線程機(jī)會(huì)進(jìn)行必要的清理工作,這在任何一個(gè)多線程應(yīng)用程序中都是絕對(duì)需要的。請(qǐng)確認(rèn)將共享變量定義成volatile 類型或?qū)?duì)它的一切訪問封入同步的塊/方法(synchronized blocks/methods)中。到目前為止一切順利!但是,當(dāng)線程等待某些事件發(fā)生而被阻塞,又會(huì)發(fā)生什么?當(dāng)然,如果線程被阻塞,它便不能核查共享變量,也就不能停止。這在許多情況下會(huì)發(fā)生,例如調(diào)用Object.wait()、ServerSocket.accept()和DatagramS
10、ocket.receive()時(shí),這里僅舉出一些。他們都可能永久的阻塞線程。即使發(fā)生超時(shí),在超時(shí)期滿之前持續(xù)等待也是不可行和不適當(dāng)?shù)?,所以,要使用某種機(jī)制使得線程更早地退出被阻塞的狀態(tài)。很不幸運(yùn),不存在這樣一種機(jī)制對(duì)所有的情況都適用,但是,根據(jù)情況不同卻可以使用特定的技術(shù)。在下面的環(huán)節(jié),我將解答一下最普遍的例子。使用Terrupt()中斷線程 正如Listing A中所描述的,Terrupt()方法不會(huì)中斷一個(gè)正在運(yùn)行的線程。這一方法實(shí)際上完成的是,在線程受到阻塞時(shí)拋出一個(gè)中斷信號(hào),這樣線程就得以退出阻塞的狀態(tài)。更確切的說,如果線程被Object.wait,
11、 Thread.join和Thread.sleep三種方法之一阻塞,那么,它將接收到一個(gè)中斷異常(InterruptedException),從而提早地終結(jié)被阻塞狀態(tài)。 因此,如果線程被上述幾種方法阻塞,正確的停止線程方式是設(shè)置共享變量,并調(diào)用interrupt()(注意變量應(yīng)該先設(shè)置)。如果線程沒有被阻塞,這時(shí)調(diào)用interrupt()將不起作用;否則,線程就將得到異常(該線程必須事先預(yù)備好處理此狀況),接著逃離阻塞狀態(tài)。在任何一種情況中,最后線程都將檢查共享變量然后再停止。Listing C這個(gè)示例描述了該技術(shù)。Listing Cclass Example3 extends Thread
12、volatile boolean stop = false; public static void main( String args ) throws Exception Example3 thread = new Example3(); System.out.println( "Starting thread." ); thread.start(); Thread.sleep( 3000 ); System.out.println( "Asking thread to stop." ); thread.stop = true;/如果線程阻塞,將不會(huì)檢
13、查此變量 errupt(); Thread.sleep( 3000 ); System.out.println( "Stopping application." ); /System.exit( 0 ); public void run() while ( !stop ) System.out.println( "Thread running." ); try Thread.sleep( 1000 ); catch ( InterruptedException e ) System.out.println( "Thread
14、interrupted." ); System.out.println( "Thread exiting under request." ); 一旦Listing C中的Terrupt()被調(diào)用,線程便收到一個(gè)異常,于是逃離了阻塞狀態(tài)并確定應(yīng)該停止。運(yùn)行以上代碼將得到下面的輸出:Starting thread.Thread running.Thread running.Thread running.Asking thread to stop.Thread interrupted.Thread exiting under request.Stopp
15、ing application.中斷I/O操作 然而,如果線程在I/O操作進(jìn)行時(shí)被阻塞,又會(huì)如何?I/O操作可以阻塞線程一段相當(dāng)長(zhǎng)的時(shí)間,特別是牽扯到網(wǎng)絡(luò)應(yīng)用時(shí)。例如,服務(wù)器可能需要等待一個(gè)請(qǐng)求(request),又或者,一個(gè)網(wǎng)絡(luò)應(yīng)用程序可能要等待遠(yuǎn)端主機(jī)的響應(yīng)。如果你正使用通道(channels)(這是在Java 1.4中引入的新的I/O API),那么被阻塞的線程將收到一個(gè)ClosedByInterruptException異常。如果情況是這樣,其代碼的邏輯和第三個(gè)例子中的是一樣的,只是異常不同而已。但是,你可能正使用Java1.0之前就存在的傳統(tǒng)的I/O,而且要求更多的工作。既然這樣,T
16、errupt()將不起作用,因?yàn)榫€程將不會(huì)退出被阻塞狀態(tài)。Listing D描述了這一行為。盡管interrupt()被調(diào)用,線程也不會(huì)退出被阻塞狀態(tài)Listing Dimport java.io.*;class Example4 extends Thread public static void main( String args ) throws Exception Example4 thread = new Example4(); System.out.println( "Starting thread." ); thread.start(); Th
17、read.sleep( 3000 ); System.out.println( "Interrupting thread." ); errupt(); Thread.sleep( 3000 ); System.out.println( "Stopping application." ); /System.exit( 0 ); public void run() ServerSocket socket; try socket = new ServerSocket(7856); catch ( IOException e ) System
18、.out.println( "Could not create the socket." ); return; while ( true ) System.out.println( "Waiting for connection." ); try Socket sock = socket.accept(); catch ( IOException e ) System.out.println( "accept() failed or interrupted." ); 很幸運(yùn),Java平臺(tái)為這種情形提供了一項(xiàng)解決方案,即調(diào)用阻塞該線程的
19、套接字的close()方法。在這種情形下,如果線程被I/O操作阻塞,該線程將接收到一個(gè)SocketException異常,這與使用interrupt()方法引起一個(gè)InterruptedException異常被拋出非常相似。唯一要說明的是,必須存在socket的引用(reference),只有這樣close()方法才能被調(diào)用。這意味著socket對(duì)象必須被共享。Listing E描述了這一情形。運(yùn)行邏輯和以前的示例是相同的。Listing Eimport .*;import java.io.*;class Example5 extends Thread volatile boolean sto
20、p = false; volatile ServerSocket socket; public static void main( String args ) throws Exception Example5 thread = new Example5(); System.out.println( "Starting thread." ); thread.start(); Thread.sleep( 3000 ); System.out.println( "Asking thread to stop." ); thread.stop = true; thread.socket.close(); Thread.sleep( 3000 ); System.out.println( "Stopping application." ); /System.e
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度文化產(chǎn)品出口代理協(xié)議模板3篇
- 2025年度征收補(bǔ)償與安置補(bǔ)償協(xié)議執(zhí)行監(jiān)督辦法4篇
- 2024年04月湖南國(guó)家開發(fā)銀行湖南分行暑期實(shí)習(xí)生招考筆試歷年參考題庫附帶答案詳解
- 個(gè)人汽車租借協(xié)議2024年標(biāo)準(zhǔn)格式樣張版B版
- 2025年度文化創(chuàng)意產(chǎn)業(yè)園區(qū)場(chǎng)地租賃管理協(xié)議4篇
- 個(gè)人與公司買賣合同范本完整版
- 2025年度文化產(chǎn)業(yè)園區(qū)場(chǎng)地合作開發(fā)合同協(xié)議書4篇
- 2024版室外房屋墻面裝修合同書版B版
- 2025年度化妝品全球包銷代理合同范本4篇
- 2024裝飾裝修合同的法律適用
- 2023年全國(guó)統(tǒng)一建筑工程預(yù)算工程量計(jì)算規(guī)則完整版
- 教科版四年級(jí)科學(xué)下冊(cè)第三單元巖石與土壤4.制作巖石和礦物標(biāo)本(教學(xué)設(shè)計(jì))教案
- 大學(xué)《工程力學(xué)》期末考試試題庫含詳細(xì)答案
- 2022年湖北省武漢市中考數(shù)學(xué)試卷含解析
- TLFSA 003-2020 危害分析與關(guān)鍵控制點(diǎn)(HACCP)體系調(diào)味面制品生產(chǎn)企業(yè)要求
- LY/T 2244.3-2014自然保護(hù)區(qū)保護(hù)成效評(píng)估技術(shù)導(dǎo)則第3部分:景觀保護(hù)
- 紀(jì)律教育月批評(píng)與自我批評(píng)五篇
- GB/T 26480-2011閥門的檢驗(yàn)和試驗(yàn)
- GB/T 13342-2007船用往復(fù)式液壓缸通用技術(shù)條件
- 藥店員工教育培訓(xùn)資料
- GB 20371-2016食品安全國(guó)家標(biāo)準(zhǔn)食品加工用植物蛋白
評(píng)論
0/150
提交評(píng)論