最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java interrupt()方法使用注意_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

 更新時(shí)間:2017年05月23日 09:33:14   投稿:mrr  
這篇文章主要介紹了Java interrupt()方法使用注意_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下

程序是很簡(jiǎn)易的。然而,在編程人員面前,多線程呈現(xiàn)出了一組新的難題,如果沒(méi)有被恰當(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è)程序。雖然初次看來(lái)它可能顯得簡(jiǎn)單,但是,你必須進(jìn)行一些預(yù)警以實(shí)現(xiàn)期望的結(jié)果。你最好還是牢記以下的幾點(diǎn)告誡。

    首先,忘掉Thread.stop方法。雖然它確實(shí)停止了一個(gè)正在運(yùn)行的線程,然而,這種方法是不安全也是不受提倡的,這意味著,在未來(lái)的Java版本中,它將不復(fù)存在。

    一些輕率的家伙可能被另一種方法Thread.interrupt所迷惑。盡管,其名稱似乎在暗示著什么,然而,這種方法并不會(huì)中斷一個(gè)正在運(yùn)行的線程(待會(huì)將進(jìn)一步說(shuō)明),正如Listing A中描述的那樣。它創(chuàng)建了一個(gè)線程,并且試圖使用Thread.interrupt方法停止該線程。Thread.sleep()方法的調(diào)用,為線程的初始化和中止提供了充裕的時(shí)間。線程本身并不參與任何有用的操作。

Listing A 

class Example1 extends Thread { 
    boolean stop=false; 
    public static void main( String args[] ) throws Exception { 
    Example1 thread = new Example1(); 
    System.out.println( "Starting thread..." ); 
    thread.start(); 
    Thread.sleep( 3000 ); 
    System.out.println( "Interrupting thread..." ); 
    thread.interrupt(); 
    Thread.sleep( 3000 ); 
    System.out.println("Stopping application..." ); 
    //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 thread...
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...
...............................

甚至,在Thread.interrupt()被調(diào)用后,線程仍然繼續(xù)運(yùn)行。

真正地中斷一個(gè)線程

    中斷線程最好的,最受推薦的方式是,使用共享變量(shared variable)發(fā)出信號(hào),告訴線程必須停止正在運(yùn)行的任務(wù)。線程必須周期性的核查這一變量(尤其在冗余操作期間),然后有秩序地中止任務(wù)。Listing B描述了這一方式。

Listing B 

class 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(); 
 Thread.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 = System.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 exiting under request...
Stopping application...

   雖然該方法要求一些編碼,但并不難實(shí)現(xiàn)。同時(shí),它給予線程機(jī)會(huì)進(jìn)行必要的清理工作,這在任何一個(gè)多線程應(yīng)用程序中都是絕對(duì)需要的。請(qǐng)確認(rèn)將共享變量定義成volatile 類型或?qū)?duì)它的一切訪問(wèn)封入同步的塊/方法(synchronized blocks/methods)中。

到目前為止一切順利!但是,當(dāng)線程等待某些事件發(fā)生而被阻塞,又會(huì)發(fā)生什么?當(dāng)然,如果線程被阻塞,它便不能核查共享變量,也就不能停止。這在許多情況下會(huì)發(fā)生,例如調(diào)用Object.wait()、ServerSocket.accept()和DatagramSocket.receive()時(shí),這里僅舉出一些。

他們都可能永久的阻塞線程。即使發(fā)生超時(shí),在超時(shí)期滿之前持續(xù)等待也是不可行和不適當(dāng)?shù)?,所以,要使用某種機(jī)制使得線程更早地退出被阻塞的狀態(tài)。

很不幸運(yùn),不存在這樣一種機(jī)制對(duì)所有的情況都適用,但是,根據(jù)情況不同卻可以使用特定的技術(shù)。在下面的環(huán)節(jié),我將解答一下最普遍的例子。

使用Thread.interrupt()中斷線程

  正如Listing A中所描述的,Thread.interrupt()方法不會(huì)中斷一個(gè)正在運(yùn)行的線程。這一方法實(shí)際上完成的是,在線程受到阻塞時(shí)拋出一個(gè)中斷信號(hào),這樣線程就得以退出阻塞的狀態(tài)。更確切的說(shuō),如果線程被Object.wait, Thread.join和Thread.sleep三種方法之一阻塞,那么,它將接收到一個(gè)中斷異常(InterruptedException),從而提早地終結(jié)被阻塞狀態(tài)。

    因此,如果線程被上述幾種方法阻塞,正確的停止線程方式是設(shè)置共享變量,并調(diào)用interrupt()(注意變量應(yīng)該先設(shè)置)。如果線程沒(méi)有被阻塞,這時(shí)調(diào)用interrupt()將不起作用;否則,線程就將得到異常(該線程必須事先預(yù)備好處理此狀況),接著逃離阻塞狀態(tài)。在任何一種情況中,最后線程都將檢查共享變量然后再停止。Listing C這個(gè)示例描述了該技術(shù)。

Listing C

 class Example3 extends Thread { 
 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ì)檢查此變量 
 thread.interrupt(); 
 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 interrupted..." ); 
  } 
  } 
 System.out.println( "Thread exiting under request..." ); 
 } 
 } 

一旦Listing C中的Thread.interrupt()被調(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...
Stopping 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,而且要求更多的工作。既然這樣,Thread.interrupt()將不起作用,因?yàn)榫€程將不會(huì)退出被阻塞狀態(tài)。Listing D描述了這一行為。盡管interrupt()被調(diào)用,線程也不會(huì)退出被阻塞狀態(tài)

Listing D

 import 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(); 
 Thread.sleep( 3000 ); 
 System.out.println( "Interrupting thread..." ); 
 thread.interrupt(); 
 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.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)用阻塞該線程的套接字的close()方法。在這種情形下,如果線程被I/O操作阻塞,該線程將接收到一個(gè)SocketException異常,這與使用interrupt()方法引起一個(gè)InterruptedException異常被拋出非常相似。

唯一要說(shuō)明的是,必須存在socket的引用(reference),只有這樣close()方法才能被調(diào)用。這意味著socket對(duì)象必須被共享。Listing E描述了這一情形。運(yùn)行邏輯和以前的示例是相同的。

Listing E

 import java.net.*; 
 import java.io.*; 
 class Example5 extends Thread { 
 volatile boolean stop = 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.exit( 0 ); 
 } 
 public void run() { 
  try { 
  socket = new ServerSocket(7856); 
  } catch ( IOException e ) { 
  System.out.println( "Could not create the socket..." ); 
  return; 
  } 
  while ( !stop ) { 
  System.out.println( "Waiting for connection..." ); 
  try { 
  Socket sock = socket.accept(); 
  } catch ( IOException e ) { 
  System.out.println( "accept() failed or interrupted..." ); 
  } 
  } 
 System.out.println( "Thread exiting under request..." ); 
 } 
 } 

以下是運(yùn)行Listing E中代碼后的輸出:

Starting thread...
Waiting for connection...
Asking thread to stop...
accept() failed or interrupted...
Thread exiting under request...
Stopping application...

多線程是一個(gè)強(qiáng)大的工具,然而它正呈現(xiàn)出一系列難題。其中之一是如何中斷一個(gè)正在運(yùn)行的線程。如果恰當(dāng)?shù)貙?shí)現(xiàn),使用上述技術(shù)中斷線程將比使用Java平臺(tái)上已經(jīng)提供的內(nèi)嵌操作更為簡(jiǎn)單。

以上所述是小編給大家介紹的Java interrupt()方法使用注意,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 在mybatis中使用mapper進(jìn)行if條件判斷

    在mybatis中使用mapper進(jìn)行if條件判斷

    這篇文章主要介紹了在mybatis中使用mapper進(jìn)行if條件判斷,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • Java設(shè)計(jì)模式之觀察者模式詳解

    Java設(shè)計(jì)模式之觀察者模式詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式之觀察者模式詳解,對(duì)象之間的多對(duì)一依賴的一種設(shè)計(jì)方案,被依賴的對(duì)象為Subject,依賴的對(duì)象為Observer,Subject通知Observer變化,需要的朋友可以參考下
    2023-12-12
  • 如何利用反射批量修改java類某一屬性的代碼詳解

    如何利用反射批量修改java類某一屬性的代碼詳解

    這篇文章主要介紹了如何利用反射批量修改java類某一屬性,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java?獲取Zookeeper節(jié)點(diǎn)下所有數(shù)據(jù)詳細(xì)步驟

    Java?獲取Zookeeper節(jié)點(diǎn)下所有數(shù)據(jù)詳細(xì)步驟

    本文介紹了如何使用Java獲取ZooKeeper節(jié)點(diǎn)下所有數(shù)據(jù),實(shí)際應(yīng)用示例中,我們演示了如何從ZooKeeper節(jié)點(diǎn)下獲取配置信息并輸出到控制臺(tái),ZooKeeper是一個(gè)開(kāi)源的分布式協(xié)調(diào)服務(wù),適用于分布式系統(tǒng)中的數(shù)據(jù)同步、配置管理、命名服務(wù)等功能,感興趣的朋友一起看看吧
    2024-11-11
  • servlet實(shí)現(xiàn)簡(jiǎn)單的權(quán)限管理和敏感詞過(guò)濾功能

    servlet實(shí)現(xiàn)簡(jiǎn)單的權(quán)限管理和敏感詞過(guò)濾功能

    JavaEE課要求用servlet和過(guò)濾器實(shí)現(xiàn)權(quán)限管理和敏感詞過(guò)濾功能,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 用Java編程輸出萬(wàn)年歷的功能實(shí)現(xiàn)

    用Java編程輸出萬(wàn)年歷的功能實(shí)現(xiàn)

    這篇文章主要介紹了用Java編程輸出萬(wàn)年歷的功能實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Java操作redis實(shí)現(xiàn)增刪查改功能的方法示例

    Java操作redis實(shí)現(xiàn)增刪查改功能的方法示例

    這篇文章主要介紹了Java操作redis實(shí)現(xiàn)增刪查改功能的方法,涉及java操作redis數(shù)據(jù)庫(kù)的連接、設(shè)置、增刪改查、釋放資源等相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • 詳解OpenFeign服務(wù)調(diào)用(微服務(wù))

    詳解OpenFeign服務(wù)調(diào)用(微服務(wù))

    OpenFeign是Spring Cloud在Feign的基礎(chǔ)上支持了SpringMVC的注解,如@RequesMapping等等,這篇文章主要介紹了OpenFeign服務(wù)調(diào)用的相關(guān)知識(shí),需要的朋友可以參考下
    2022-07-07
  • SpringMVC框架的介紹與使用詳解

    SpringMVC框架的介紹與使用詳解

    SpringMVC?是一種基于?Java?的實(shí)現(xiàn)?MVC?設(shè)計(jì)模型的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)?Web?框架,跟Spring,Mybatis框架并稱為ssm,這篇文章主要介紹了SpringMVC框架的介紹與使用,需要的朋友可以參考下
    2022-08-08
  • 使用SpringBoot 配置Oracle和H2雙數(shù)據(jù)源及問(wèn)題

    使用SpringBoot 配置Oracle和H2雙數(shù)據(jù)源及問(wèn)題

    這篇文章主要介紹了使用SpringBoot 配置Oracle和H2雙數(shù)據(jù)源及問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評(píng)論

观塘区| 盖州市| 申扎县| 衡阳县| 余姚市| 肥城市| 东丽区| 鸡西市| 新沂市| 江川县| 襄汾县| 辽中县| 扶余县| 靖江市| 兰西县| 饶阳县| 枣阳市| 玉门市| 克什克腾旗| 焦作市| 江达县| 儋州市| 商水县| 津市市| 宜良县| 古丈县| 密山市| 周至县| 安丘市| 前郭尔| 伊通| 色达县| 桑植县| 台安县| 县级市| 武宣县| 三都| 绥德县| 长兴县| 普兰店市| 改则县|