隨筆 - 22, 文章 - 0, 評論 - 1, 引用 - 0
          數(shù)據(jù)加載中……

          java中Thread合理的中止,退出,暫停方式

          最近研究Thread時看到篇好文《Java 理論與實(shí)踐: 處理 InterruptedException》,摘錄下來備用:
          http://www.ibm.com/developerworks/cn/java/j-jtp05236.html
          1,當(dāng)一個方法拋出 InterruptedException 時,它不僅告訴您它可以拋出一個特定的檢查異常,而且還告訴您其他一些事情。例如,它告訴您它是一個阻塞(blocking)方法,如果您響應(yīng)得當(dāng)?shù)脑挘鼘L試消除阻塞并盡早返回。
          2,當(dāng)一個方法拋出 InterruptedException 時,它是在告訴您,如果執(zhí)行該方法的線程被中斷,它將嘗試停止它正在做的事情而提前返回,并通過拋出 InterruptedException 表明它提前返回。 行為良好的阻塞庫方法應(yīng)該能對中斷作出響應(yīng)并拋出 InterruptedException,以便能夠用于可取消活動中,而不至于影響響應(yīng)。
          3,如果拋出 InterruptedException 意味著一個方法是阻塞方法,那么調(diào)用一個阻塞方法則意味著您的方法也是一個阻塞方法,而且您應(yīng)該有某種策略來處理 InterruptedException。通常最容易的策略是執(zhí)行清理,然后自己拋出 InterruptedException,將它傳播給調(diào)用者。
          4,如果捕捉到 InterruptedException 但是不能重新拋出它,那么應(yīng)該保留中斷發(fā)生的證據(jù),以便調(diào)用棧中更高層的代碼能知道中斷,并對中斷作出響應(yīng)。該任務(wù)可以通過調(diào)用當(dāng)前線程的interrupt() 以 “中斷當(dāng)前線程自己” 來完成。
          5,對于執(zhí)行一個循環(huán)中的代碼的任務(wù),通常只需為每一個循環(huán)迭代檢查一次中斷。取決于循環(huán)執(zhí)行的時間有多長,任何代碼可能要花一些時間才能注意到線程已經(jīng)被中斷(或者是通過調(diào)用 Thread.isInterrupted() 方法輪詢中斷狀態(tài),或者是調(diào)用一個阻塞方法)。
          6,不可中斷的阻塞方法:并非所有的阻塞方法都拋出 InterruptedException。輸入和輸出流類會阻塞等待 I/O 完成,但是它們不拋出 InterruptedException,而且在被中斷的情況下也不會提前返回。然而,對于套接字 I/O,如果一個線程關(guān)閉套接字,則那個套接字上的阻塞 I/O 操作將提前結(jié)束,并拋出一個 SocketException。java.nio 中的非阻塞 I/O 類也不支持可中斷 I/O,但是同樣可以通過關(guān)閉通道或者請求 Selector 上的喚醒來取消阻塞操作。

          另據(jù)別的文章(忘了出處了):
          interrupt方法其實(shí)只是改變了中斷狀態(tài)而已,而sleep、wait和join這些方法的內(nèi)部會不斷的檢查中斷狀態(tài)的值,從而自己拋出InterruptEdException。
          ——所以該異常從“設(shè)置”到“拋出”不是即時的,但是只要調(diào)用過程有上述方法之一,就會最終檢測到終端狀態(tài)并拋出異常。

          Thread類中destory,resume,stop,suspend這些廢棄方法引用了一篇說明文章:
          《Why Are Thread.stop, Thread.suspend,Thread.resume and Runtime.runFinalizersOnExit Deprecated?》
          http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
          以下是根據(jù)其寫的demo:

            1 /**
            2  * @author watchzerg
            3  */
            4 public class ThreadManager implements Runnable{
            5     //線程對象引用
            6     private Thread myThread;
            7     //休眠間隔
            8     private long interval=1000l;
            9     //用volatile保證變量同步
           10     private volatile boolean threadSuspended;
           11 
           12     //開始
           13     public void start(){
           14         myThread=new Thread(this,"myThread");
           15         myThread.start();
           16     }
           17     
           18     /**
           19      * 線程體(執(zhí)行內(nèi)容):
           20      * 如果線程不需要sleep之類的阻塞方法,
           21      * 可以通過Thread.isInterrupted()方法來檢測中斷
           22      */
           23     @Override
           24     public void run() {
           25         Thread thisThread=Thread.currentThread();
           26         while(myThread==thisThread){
           27             try{
           28                 Thread.sleep(interval);
           29                 System.out.println(myThread.getName()+" is running.");
           30                 //先if一下,避免每次都進(jìn)入同步塊帶來的開銷
           31                 if(threadSuspended&&myThread==thisThread){
           32                     synchronized(this){
           33                         /* 如果線程在suspend狀態(tài)被stop,那么myThread==null
           34                          * 它在下一個循環(huán)就快速退出,不再等待了
           35                          * 不過話說,wait方法本身也會拋中斷異常的
           36                          * 所以我覺得這里去掉"myThread==thisThread"也行
           37                          * 元方,你怎么看?
           38                          * */
           39                         while(threadSuspended&&myThread==thisThread){
           40                             wait();
           41                         }
           42                     }
           43                 }
           44             }catch(InterruptedException e){
           45                 System.out.println(thisThread.getName()+
           46                         " is interrupted by InterruptedException.");
           47                 //如果這里不打算處理此異常,而又無法拋出去,可以重新斷言自己:
           48                 //Thread.currentThread().interrupt();
           49             }
           50         }
           51         System.out.println(thisThread.getName()+": I'm out, do you copy? ");
           52     }
           53     
           54     /**
           55      * 停止線程:
           56      * 如果是sleep狀態(tài),是interrupt起作用;
           57      * 如果是運(yùn)行狀態(tài),是myThread==null終止了循環(huán)
           58      */
           59     public synchronized void stop(){
           60         if(myThread==null){
           61             return;
           62         }
           63         Thread moribund=myThread;
           64         myThread=null;
           65         moribund.interrupt();
           66     }
           67     
           68     /**
           69      * 掛起線程:
           70      * 反轉(zhuǎn)條件,并通知其它等待線程
           71      */
           72     public synchronized void suspend(){
           73         threadSuspended=!threadSuspended;
           74         if(!threadSuspended){
           75             notify();
           76         }
           77     }
           78     
           79     //test
           80     public static void main(String[] args) throws Exception {
           81         ThreadManager manager=new ThreadManager();
           82         //開始
           83         manager.start();
           84         System.out.println("sys:starting");
           85         Thread.sleep(10000l);
           86         //暫停
           87         manager.suspend();
           88         System.out.println("sys:suspend");
           89         Thread.sleep(10000l);
           90         //恢復(fù)
           91         manager.suspend();
           92         System.out.println("sys:resume");
           93         Thread.sleep(10000l);
           94         //暫停
           95         manager.suspend();
           96         System.out.println("sys:suspend");
           97         Thread.sleep(5000l);
           98         //在暫停狀態(tài)下停止
           99         manager.stop();
          100         System.out.println("sys:stop");
          101         Thread.sleep(10000l);
          102         //退出
          103         System.out.println("sys:exitnow what?");
          104     }
          105 }

          posted on 2012-11-17 20:24 王星游 閱讀(17651) 評論(0)  編輯  收藏 所屬分類: java

          主站蜘蛛池模板: 黄骅市| 保定市| 如东县| 阳春市| 乐清市| 秦安县| 博客| 太仓市| 泗洪县| 郁南县| 从化市| 崇信县| 乐昌市| 蓝山县| 平乐县| 崇阳县| 西丰县| 台安县| 高雄市| 凤庆县| 郎溪县| 环江| 枝江市| 玛沁县| 岳西县| 馆陶县| 衡阳县| 磴口县| 新兴县| 若羌县| 温州市| 南乐县| 甘肃省| 河东区| 云和县| 枣庄市| 壤塘县| 青川县| 揭东县| 垫江县| 桃江县|