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:exit
now what?");
104 }
105 }
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:exit

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