随笔 - 22, 文章 - 0, 评论 - 1, 引用 - 0
数据加载中……

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

最近研究Thread时看到篇好文《Java 理论与实践: 处理 InterruptedException》,摘录下来备用:
http://www.ibm.com/developerworks/cn/java/j-jtp05236.html
1,当一个方法抛出 InterruptedException 时,它不仅告诉您它可以抛出一个特定的检查异常,而且还告诉您其他一些事情。例如,它告诉您它是一个阻塞(blocking)方法,如果您响应得当的话,它将尝试消除阻塞并尽早返回。
2,当一个方法抛出 InterruptedException 时,它是在告诉您,如果执行该方法的线程被中断,它将尝试停止它正在做的事情而提前返回,并通过抛出 InterruptedException 表明它提前返回。 行为良好的阻塞库方法应该能对中断作出响应并抛出 InterruptedException,以便能够用于可取消活动中,而不至于影响响应。
3,如果抛出 InterruptedException 意味着一个方法是阻塞方法,那么调用一个阻塞方法则意味着您的方法也是一个阻塞方法,而且您应该有某种策略来处理 InterruptedException。通常最容易的策略是执行清理,然后自己抛出 InterruptedException,将它传播给调用者。
4,如果捕捉到 InterruptedException 但是不能重新抛出它,那么应该保留中断发生的证据,以便调用栈中更高层的代码能知道中断,并对中断作出响应。该任务可以通过调用当前线程的interrupt() 以 “中断当前线程自己” 来完成。
5,对于执行一个循环中的代码的任务,通常只需为每一个循环迭代检查一次中断。取决于循环执行的时间有多长,任何代码可能要花一些时间才能注意到线程已经被中断(或者是通过调用 Thread.isInterrupted() 方法轮询中断状态,或者是调用一个阻塞方法)。
6,不可中断的阻塞方法:并非所有的阻塞方法都抛出 InterruptedException。输入和输出流类会阻塞等待 I/O 完成,但是它们不抛出 InterruptedException,而且在被中断的情况下也不会提前返回。然而,对于套接字 I/O,如果一个线程关闭套接字,则那个套接字上的阻塞 I/O 操作将提前结束,并抛出一个 SocketException。java.nio 中的非阻塞 I/O 类也不支持可中断 I/O,但是同样可以通过关闭通道或者请求 Selector 上的唤醒来取消阻塞操作。

另据别的文章(忘了出处了):
interrupt方法其实只是改变了中断状态而已,而sleep、wait和join这些方法的内部会不断的检查中断状态的值,从而自己抛出InterruptEdException。
——所以该异常从“设置”到“抛出”不是即时的,但是只要调用过程有上述方法之一,就会最终检测到终端状态并抛出异常。

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
以下是根据其写的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      * 线程体(执行内容):
 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一下,避免每次都进入同步块带来的开销
 31                 if(threadSuspended&&myThread==thisThread){
 32                     synchronized(this){
 33                         /* 如果线程在suspend状态被stop,那么myThread==null
 34                          * 它在下一个循环就快速退出,不再等待了
 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状态,是interrupt起作用;
 57      * 如果是运行状态,是myThread==null终止了循环
 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      * 反转条件,并通知其它等待线程
 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         //恢复
 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         //在暂停状态下停止
 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 王星游 阅读(17611) 评论(0)  编辑  收藏 所属分类: java


只有注册用户登录后才能发表评论。


网站导航: