A-A+

java中断小记

2016年02月20日 站长资讯 暂无评论

java中与中断相关的函数有如下三个:

1.通过成员方法Thread.interrupt()来设置中断状态为true

2.通过成员方法Thread.isInterrupted()来获取中断状态

3.通过静态方法Thread.interrupted()来获取中断状态,并且清除中断状态(当然获取的是清除之前的值),也就是说连续两次调用此方法,第二次一定会返回false。

下面详细介绍各个方法。

成员方法new Thread().interrupt()

线程的成员方法new Thread().interrupt()是中断线程,设置该线程的中断状态位,即设置为true(默认为false),中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法(很少用stop来结束线程,用共享变量或者别的方法实现线程的结束)那样会中断一个正在运行的线程。

但是interrupt()方法并不能中断正在运行(有关线程状态请参考http://yimaoqian.blog.51cto.com/1328422/1399767这篇博文)的线程,程序实例如下:

  1. public class TestSun {  
  2.     public static void main(String[] args){  
  3.         // test1  
  4.         Thread t1 = new Thread(){  
  5.             @Override  
  6.             public void run(){  
  7.                 try{  
  8.                     int i=0;  
  9.                     while(i++<100000000){  
  10.                         // nothing  
  11.                     }  
  12.   
  13.   
  14.                     System.out.println("A1");  
  15.                 }catch(Exception e){  
  16.                     System.out.println("B1");  
  17.             };  
  18.         };  
  19.         t1.start();       
  20.         System.out.println(t1.isInterrupted() + " before");//查看线程是否中断(中断标志位)  
  21.         t1.interrupt();//不中断正在运行的线程  
  22.         System.out.println(t1.isInterrupted() + " after");  
  23.     }  
  24. }   
  25.    
  26. ---------------------------  
  27. 运行结果:  
  28. false before  
  29. true after  
  30. A1  

由运行结果分析出t1.interrupt()并没有中断线程t1,即得出结论成员方法interrupt()方法对正在运行的方法(即没有阻塞)不起作用,只对处于阻塞中的线程起作用。

interrupt()方法中断处于阻塞状态(此处的阻塞状态不包括因IO操作引起的阻塞,只包括wait、join、sleep)的线程时,会抛出InterruptedException异常,并且将中断状态被清除(即将调用interrupt()方法时设置的true清除,变为false),程序实例:

  1. public class TestSun {  
  2.     public static void main(String[] args){  
  3.         // test1  
  4.         Thread t1 = new Thread(){  
  5.             @Override  
  6.             public void run(){  
  7.                 try{  
  8.                     int i=0;  
  9.                     while(i++<100000000){  
  10.                         // nothing  
  11.                     }  
  12.   
  13.   
  14.                     System.out.println("A1");  
  15.                     Thread.sleep(5000);//阻塞线程  
  16.                 }catch(Exception e){  
  17.                     System.out.println("B1");  
  18.                     //抛出异常之后中断标志位才清除  
  19.                     System.out.println(Thread.currentThread().isInterrupted() + " in catch");                      
  20.                 }  
  21.             };  
  22.         };  
  23.         t1.start();         
  24.         System.out.println(t1.isInterrupted() + " before");  
  25.         t1.interrupt();//不中断正在运行的线程  
  26.         System.out.println(t1.isInterrupted() + " after");  
  27.     }  
  28. }  
  29.    
  30. --------------------------------------------  
  31. 运行结果:  
  32. false before  
  33. true after  
  34. A1  
  35. B1  
  36. false in catch  

上面说到interrupt()方法无法中断因IO操作引起的阻塞的线程,这里用一个程序说明下:

  1. import java.io.IOException;  
  2. import java.net.ServerSocket;  
  3. import java.net.Socket;  
  4.    
  5. public class Exemple4 extends Thread {  
  6.       public static void main( String args[] ) throws Exception {  
  7.    
  8.             Exemple4 thread = new Exemple4();  
  9.    
  10.            System.out.println( "Starting thread..." );  
  11.    
  12.            thread.start();  
  13.    
  14.            Thread.sleep( 3000 );  
  15.    
  16.            System.out.println( "Interrupting thread..." );  
  17.    
  18.            thread.interrupt();  
  19.    
  20.            Thread.sleep( 3000 );  
  21.   
  22.   
  23.    
  24.            System.out.println( "Stopping application..." );  
  25.           }  
  26.    
  27.           public void run() {  
  28.    
  29.            ServerSocket socket;  
  30.    
  31.             try {  www.xiaoxiongboke.com/  
  32.    
  33.               socket = new ServerSocket(7856);  
  34.    
  35.             } catch ( IOException e ) {  
  36.    
  37.              System.out.println( "Could not create the socket..." );  
  38.    
  39.               return;   
  40.    
  41.             }  
  42.    
  43.             while ( true ) {  
  44.    
  45.              System.out.println( "Waiting for connection..." );  
  46.    
  47.               try {  
  48.    
  49.                Socket sock = socket.accept();  
  50.    
  51.               } catch ( IOException e ) {  
  52.    
  53.               System.out.println( "accept() failed or interrupted..." );  
  54.    
  55.               }  
  56.    
  57.             }   
  58.    
  59.           }  
  60. }  
  61.    
  62. -------------------------------------------  
  63. 运行结果:  
  64. Starting thread...  
  65. Waiting for connection...  
  66. Interrupting thread...  
  67. Stopping application...  

其实interrupt()方法还不能中断死锁状态的线程,因为锁定的位置根本无法抛出异常,程序示例:

  1. public class Exemple4 extends Thread {  
  2.     public static void main(String args[]) throws Exception {  
  3.         final Object lock1 = new Object();  
  4.         final Object lock2 = new Object();  
  5.         Thread thread1 = new Thread() {  
  6.             public void run() {  
  7.                 deathLock(lock1, lock2);  
  8.             }  
  9.         };  
  10.         Thread thread2 = new Thread() {  
  11.             public void run() {  
  12.                 // 注意,这里在交换了一下位置  
  13.   
  14.   
  15.                 deathLock(lock2, lock1);  
  16.             }  
  17.         };  
  18.         System.out.println("Starting thread...");  
  19.         thread1.start();  
  20.         thread2.start();  
  21.         Thread.sleep(3000);  
  22.         System.out.println("Interrupting thread...");  
  23.         thread1.interrupt();  
  24.         thread2.interrupt();  
  25.         Thread.sleep(3000);  
  26.         System.out.println("Stopping application...");  
  27.     }  
  28.     
  29.     static void deathLock(Object lock1, Object lock2) {  
  30.         try {  
  31.             synchronized (lock1) {  
  32.                 Thread.sleep(10);// 不会在这里死掉  
  33.                // System.out.println(lock1 + " thread...");  
  34.                 synchronized (lock2) {// 会锁在这里,虽然阻塞了,但不会抛异常  
  35.                     System.out.println(Thread.currentThread());  
  36.                 }  
  37.             }  
  38.         } catch (InterruptedException e) {   
  39.             System.out.println("exception thread...");  
  40.             e.printStackTrace();  
  41.             System.exit(1);  
  42.         }  
  43.     }  
  44.        
  45.  ----------------------  
  46.  运行结果:  
  47. Starting thread...  
  48. Interrupting thread...  
  49. Stopping application...  

当不发生死锁时,线程可以正常中断,程序实例:

  1. Thread t4 = new Thread(){  
  2.     public void run(){  
  3.         try{  
  4.             synchronized(this){  
  5.                 this.wait(50000);  
  6.             }  
  7.             System.out.println("A4");  
  8.         }catch(Exception e){  
  9.             System.out.println("B4");  
  10.   
  11.   
  12.         }  
  13.     };  
  14. };  
  15. t4.start();  
  16. t4.interrupt();    //可以中断是因为没有发生竞争上锁  
  17.    
  18. ----------------------------  
  19. 运行结果:  
  20. B4  

2.成员方法new Thread().isInterrupted()

要熄灯了,先写到这里,有时间再继续.

标签:

给我留言