欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
多線(xiàn)程編程——實(shí)戰篇(四)
多線(xiàn)程編程——實(shí)戰篇(四)

時(shí)間:2007-02-08
作者:axman
瀏覽次數: 379
本文關(guān)鍵字:Java多線(xiàn)程線(xiàn)程線(xiàn)程對象單線(xiàn)程go deep into java
文章工具
 推薦給朋友
 打印文章

  不客氣地說(shuō),至少有一半人認為,線(xiàn)程的“中斷”就是讓線(xiàn)程停止。如果你也這么認為,那你對多線(xiàn)程編程還沒(méi)有入門(mén)。

  在java中,線(xiàn)程的中斷(interrupt)只是改變了線(xiàn)程的中斷狀態(tài),至于這個(gè)中斷狀態(tài)改變后帶來(lái)的結果,那是無(wú)法確定的,有時(shí)它更是讓停止中的線(xiàn)程繼續執行的唯一手段。不但不是讓線(xiàn)程停止運行,反而是繼續執行線(xiàn)程的手段。

  對于執行一般邏輯的線(xiàn)程,如果調用它的interrupt()方法,那么對這個(gè)線(xiàn)程沒(méi)有任何影響,比如線(xiàn)程a正在執行:while(條件) x ++;這樣的語(yǔ)句,如果其它線(xiàn)程調用a.interrupt();那么并不會(huì )影響a對象上運行的線(xiàn)程,如果在其它線(xiàn)程里測試a的中斷狀態(tài)它已經(jīng)改變,但并不會(huì )停止這個(gè)線(xiàn)程的運行。在一個(gè)線(xiàn)程對象上調用interrupt()方法,真正有影響的是wait,join,sleep方法,當然這三個(gè)方法包括它們的重載方法。

  請注意:[上面這三個(gè)方法都會(huì )拋出InterruptedException],記住這句話(huà),下面我會(huì )重復。一個(gè)線(xiàn)程在調用interrupt()后,自己不會(huì )拋出InterruptedException異常,所以你看到interrupt()并沒(méi)有拋出這個(gè)異常,所以我上面說(shuō)如果線(xiàn)程a正在執行while(條件) x ++;你調用a.interrupt();后線(xiàn)程會(huì )繼續正常地執行下去。

  但是,如果一個(gè)線(xiàn)程被調用了interrupt()后,它的狀態(tài)是已中斷的。這個(gè)狀態(tài)對于正在執行wait,join,sleep的線(xiàn)程,卻改變了線(xiàn)程的運行結果。

  一、對于wait中等待notify/notifyAll喚醒的線(xiàn)程,其實(shí)這個(gè)線(xiàn)程已經(jīng)“暫停”執行,因為它正在某一對象的休息室中,這時(shí)如果它的中斷狀態(tài)被改變,那么它就會(huì )拋出異常。這個(gè)InterruptedException異常不是線(xiàn)程拋出的,而是wait方法,也就是對象的wait方法內部會(huì )不斷檢查在此對象上休息的線(xiàn)程的狀態(tài),如果發(fā)現哪個(gè)線(xiàn)程的狀態(tài)被置為已中斷,則會(huì )拋出InterruptedException,意思就是這個(gè)線(xiàn)程不能再等待了,其意義就等同于喚醒它了。

  這里唯一的區別是,被notify/All喚醒的線(xiàn)程會(huì )繼續執行wait下面的語(yǔ)句,而在wait中被中斷的線(xiàn)程則將控制權交給了catch語(yǔ)句。一些正常的邏輯要被放到catch中來(lái)運行。但有時(shí)這是唯一手段,比如一個(gè)線(xiàn)程a在某一對象b的wait中等待喚醒,其它線(xiàn)程必須獲取到對象b的監視鎖才能調用b.notify()[All],否則你就無(wú)法喚醒線(xiàn)程a,但在任何線(xiàn)程中可以無(wú)條件地調用a.interrupt();來(lái)達到這個(gè)目的。只是喚醒后的邏輯你要放在catch中,當然同notify/All一樣,繼續執行a線(xiàn)程的條件還是要等拿到b對象的監視鎖。

  二、對于sleep中的線(xiàn)程,如果你調用了Thread.sleep(一年);現在你后悔了,想讓它早些醒過(guò)來(lái),調用interrupt()方法就是唯一手段,只有改變它的中斷狀態(tài),讓它從sleep中將控制權轉到處理異常的catch語(yǔ)句中,然后再由catch中的處理轉換到正常的邏輯。同樣地,于join中的線(xiàn)程你也可以這樣處理。

  對于一般介紹多線(xiàn)程模式的書(shū)上,他們會(huì )這樣來(lái)介紹:當一個(gè)線(xiàn)程被中斷后,在進(jìn)入wait,sleep,join方法時(shí)會(huì )拋出異常。是的,這一點(diǎn)也沒(méi)有錯,但是這有什么意義呢?如果你知道那個(gè)線(xiàn)程的狀態(tài)已經(jīng)處于中斷狀態(tài),為什么還要讓它進(jìn)入這三個(gè)方法呢?當然有時(shí)是必須這么做的,但大多數時(shí)候沒(méi)有這么做的理由,所以我上面主要介紹了在已經(jīng)調用這三個(gè)方法的線(xiàn)程上調用interrupt()方法讓它從"暫停"狀態(tài)中恢復過(guò)來(lái)。這個(gè)恢復過(guò)來(lái)就可以包含兩個(gè)目的:

  一、[可以使線(xiàn)程繼續執行],那就是在catch語(yǔ)句中招待醒來(lái)后的邏輯,或由catch語(yǔ)句轉回正常的邏輯??傊菑膚ait,sleep,join的暫停狀態(tài)活過(guò)來(lái)了。

  二、[可以直接停止線(xiàn)程的運行],當然在catch中什么也不處理,或return,那么就完成了當前線(xiàn)程的使命,可以使在上面“暫停”的狀態(tài)中立即真正的“停止”。

  中斷線(xiàn)程

  有了上一節[線(xiàn)程的中斷],我們就好進(jìn)行如何[中斷線(xiàn)程]了。這絕對不是玩一個(gè)文字游戲。是因為“線(xiàn)程的中斷”并不能保證“中斷線(xiàn)程”,所以我要特別地分為兩節來(lái)說(shuō)明。這里說(shuō)的“中斷線(xiàn)程”意思是“停止線(xiàn)程”,而為什么不用“停止線(xiàn)程”這個(gè)說(shuō)法呢?因為線(xiàn)程有一個(gè)明確的stop方法,但它是反對使用的,所以請大家記住,在java中以后不要提停止線(xiàn)程這個(gè)說(shuō)法,忘記它!但是,作為介紹線(xiàn)程知識的我,我仍然要告訴你為什么不用“停止線(xiàn)程”的理由。

  [停止線(xiàn)程]

  當在一個(gè)線(xiàn)程對象上調用stop()方法時(shí),這個(gè)線(xiàn)程對象所運行的線(xiàn)程就會(huì )立即停止,并拋出特殊的ThreadDeath()異常。這里的“立即”因為太“立即”了,就象一個(gè)正在擺弄自己的玩具的孩子,聽(tīng)到大人說(shuō)快去睡覺(jué)去,就放著(zhù)滿(mǎn)地的玩具立即睡覺(jué)去了。這樣的孩子是不乖的。

  假如一個(gè)線(xiàn)程正在執行:

synchronized void {x = 3;y = 4;}

  由于方法是同步的,多個(gè)線(xiàn)程訪(fǎng)問(wèn)時(shí)總能保證x,y被同時(shí)賦值,而如果一個(gè)線(xiàn)程正在執行到x = 3;時(shí),被調用了stop()方法,即使在同步塊中,它也干脆地stop了,這樣就產(chǎn)生了不完整的殘廢數據。而多線(xiàn)程編程中最最基礎的條件要保證數據的完整性,所以請忘記線(xiàn)程的stop方法,以后我們再也不要說(shuō)“停止線(xiàn)程”了。

   如何才能“結束”一個(gè)線(xiàn)程?

  [中斷線(xiàn)程]

  結束一個(gè)線(xiàn)程,我們要分析線(xiàn)程的運行情況。也就是線(xiàn)程正在干什么。如果那個(gè)孩子什么事也沒(méi)干,那就讓他立即去睡覺(jué)。而如果那個(gè)孩子正在擺弄他的玩具,我們就要讓它把玩具收拾好再睡覺(jué)。

  所以一個(gè)線(xiàn)程從運行到真正的結束,應該有三個(gè)階段:

  1. 正常運行.
  2. 處理結束前的工作,也就是準備結束.
  3. 結束退出.

  在我的JDBC專(zhuān)欄中我N次提醒在一個(gè)SQL邏輯結束后,無(wú)論如何要保證關(guān)閉Connnection那就是在finally從句中進(jìn)行。同樣,線(xiàn)程在結束前的工作應該在finally中來(lái)保證線(xiàn)程退出前一定執行:

 try{正在邏輯}catch(){}finally{清理工作}

  那么如何讓一個(gè)線(xiàn)程結束呢?既然不能調用stop,可用的只的interrupt()方法。但interrupt()方法只是改變了線(xiàn)程的運行狀態(tài),如何讓它退出運行?對于一般邏輯,只要線(xiàn)程狀態(tài)已經(jīng)中斷,我們就可以讓它退出,所以這樣的語(yǔ)句可以保證線(xiàn)程在中斷后就能結束運行:

 while(!isInterrupted()){正常邏輯}

  這樣如果這個(gè)線(xiàn)程被調用interrupt()方法,isInterrupted()為true,就會(huì )退出運行。但是如果線(xiàn)程正在執行wait,sleep,join方法,你調用interrupt()方法,這個(gè)邏輯就不完全了。

  如果一個(gè)有經(jīng)驗的程序員來(lái)處理線(xiàn)程的運行的結束:

 public void run(){try{while(!isInterrupted()){正常工作}}catch(Exception e){return;}finally{清理工作}}

  我們看到,如果線(xiàn)程執行一般邏輯在調用innterrupt后,isInterrupted()為true,退出循環(huán)后執行清理工作后結束,即使線(xiàn)程正在wait,sleep,join,也會(huì )拋出異常執行清理工作后退出。

  這看起來(lái)非常好,線(xiàn)程完全按最我們設定的思路在工作。但是,并不是每個(gè)程序員都有這種認識,如果他聰明的自己處理異常會(huì )如何?事實(shí)上很多或大多數程序員會(huì )這樣處理:

 public void run(){while(!isInterrupted()){try{正常工作}catch(Exception e){//nothing}finally{}}}}

  想一想,如果一個(gè)正在sleep的線(xiàn)程,在調用interrupt后,會(huì )如何?wait方法檢查到isInterrupted()為true,拋出異常,而你又沒(méi)有處理。而一個(gè)拋出了InterruptedException的線(xiàn)程的狀態(tài)馬上就會(huì )被置為非中斷狀態(tài),如果catch語(yǔ)句沒(méi)有處理異常,則下一次循環(huán)中isInterrupted()為false,線(xiàn)程會(huì )繼續執行,可能你N次拋出異常,也無(wú)法讓線(xiàn)程停止。

  那么如何能確保線(xiàn)程真正停止?在線(xiàn)程同步的時(shí)候我們有一個(gè)叫“二次惰性檢測”(doublecheck),能在提高效率的基礎上又確保線(xiàn)程真正中同步控制中。那么我把線(xiàn)程正確退出的方法稱(chēng)為“雙重安全退出”,即不以isInterrupted()為循環(huán)條件。而以一個(gè)標記作為循環(huán)條件:

class MyThread extend Thread{private boolean isInterrupted = false;//這一句以后要修改public void interrupt(){isInterrupted = true;super.interrupt();}public void run(){while(!isInterrupted){try{正常工作}catch(Exception e){//nothing}finally{}}}}

  試試這段程序,可以正確工作嗎?

  對于這段程序仍然還有很多可說(shuō)的地方,先到這里吧。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
正確中斷java線(xiàn)程
FutureTask的cancel方法真的能停止掉一個(gè)正在執行的異步任務(wù)嗎
讀《Java多線(xiàn)程設計模式》備忘
Java并發(fā)編程:3-Thread類(lèi)的使用
中斷線(xiàn)程
Java多線(xiàn)程17:中斷機制
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久