java中断小记

java中与中断相关的函数有如下三个:
   1.通过成员方法Thread.interrupt()来设置中断状态为true
   2.通过成员方法Thread.isInterrupted()来获取中断状态
   3.通过静态方法Thread.interrupted()来获取中断状态,并且清除中断状态(当然获取的是清除之前的值),
也就是说连续两次调用此方法,第二次一定会返回false。

下面详细介绍各个方法。

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

    线程的成员方法new Thread().interrupt()是中断线程,设置该线程的中断状态位,即设置为true(默认为false),中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断

标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法(很少用stop来结束线程,用共享变量或者别的方法实现线程的结束)那样会中断一个正在运行的线程。

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

public class TestSun {
    public static void main(String[] args){
        // test1
        Thread t1 = new Thread(){
            @Override
            public void run(){
                try{
                    int i=0;
                    while(i++<100000000){
                        // nothing
                    }
                    System.out.println("A1");
                }catch(Exception e){
                    System.out.println("B1");
            };
        };
        t1.start();     
        System.out.println(t1.isInterrupted() + " before");//查看线程是否中断(中断标志位)
        t1.interrupt();//不中断正在运行的线程
        System.out.println(t1.isInterrupted() + " after");
    }
}

------------------------------------------------------------
运行结果:
false before
true after
A1

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

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

public class TestSun {
    public static void main(String[] args){
        // test1
        Thread t1 = new Thread(){
            @Override
            public void run(){
                try{
                    int i=0;
                    while(i++<100000000){
                        // nothing
                    }
                    System.out.println("A1");
                    Thread.sleep(5000);//阻塞线程
                }catch(Exception e){
                    System.out.println("B1");
                    //抛出异常之后中断标志位才清除
                    System.out.println(Thread.currentThread().isInterrupted() + " in catch");                    
                }
            };
        };
        t1.start();       
        System.out.println(t1.isInterrupted() + " before");
        t1.interrupt();//不中断正在运行的线程
        System.out.println(t1.isInterrupted() + " after");
    }
}

--------------------------------------------
运行结果:
false before
true after
A1
B1
false in catch

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

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Exemple4 extends Thread {
      public static void main( String args[] ) throws Exception {

            Exemple4 thread = new Exemple4();

           System.out.println( "Starting thread..." );

           thread.start();

           Thread.sleep( 3000 );

           System.out.println( "Interrupting thread..." );

           thread.interrupt();

           Thread.sleep( 3000 );

           System.out.println( "Stopping application..." );
          }

          public void run() {

           ServerSocket socket;

            try {

              socket = new ServerSocket(7856);

            } catch ( IOException e ) {

             System.out.println( "Could not create the socket..." );

              return;

            }

            while ( true ) {

             System.out.println( "Waiting for connection..." );

              try {

               Socket sock = socket.accept();

              } catch ( IOException e ) {

              System.out.println( "accept() failed or interrupted..." );

              }

            }

          }
}

-------------------------------------------
运行结果:
Starting thread...
Waiting for connection...
Interrupting thread...
Stopping application...

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

public class Exemple4 extends Thread {
    public static void main(String args[]) throws Exception {
        final Object lock1 = new Object();
        final Object lock2 = new Object();
        Thread thread1 = new Thread() {
            public void run() {
                deathLock(lock1, lock2);
            }
        };
        Thread thread2 = new Thread() {
            public void run() {
                // 注意,这里在交换了一下位置
                deathLock(lock2, lock1);
            }
        };
        System.out.println("Starting thread...");
        thread1.start();
        thread2.start();
        Thread.sleep(3000);
        System.out.println("Interrupting thread...");
        thread1.interrupt();
        thread2.interrupt();
        Thread.sleep(3000);
        System.out.println("Stopping application...");
    }

    static void deathLock(Object lock1, Object lock2) {
        try {
            synchronized (lock1) {
                Thread.sleep(10);// 不会在这里死掉
               // System.out.println(lock1 + " thread...");
                synchronized (lock2) {// 会锁在这里,虽然阻塞了,但不会抛异常
                    System.out.println(Thread.currentThread());
                }
            }
        } catch (InterruptedException e) {
            System.out.println("exception thread...");
            e.printStackTrace();
            System.exit(1);
        }
    }
    
 -----------------------------------------------------
 运行结果:
Starting thread...
Interrupting thread...
Stopping application...

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

        Thread t4 = new Thread(){
            public void run(){
                try{
                    synchronized(this){
                        this.wait(50000);
                    }
                    System.out.println("A4");
                }catch(Exception e){
                    System.out.println("B4");
                }
            };
        };
        t4.start();
        t4.interrupt();    //可以中断是因为没有发生竞争上锁
        
        ----------------------------
        运行结果:
        B4

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

 



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


本文出自 “混混” 博客,请务必保留此出处http://yimaoqian.blog.51cto.com/1328422/1544963

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。