Java 多线程--interrupt()中断

来源:互联网 发布:office for mac 2016 编辑:程序博客网 时间:2024/06/12 23:44

Thread.interrupt()方法不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.joinThread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态

使用interrupt()中断线程

当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。

/** * Created by yangtianrui on 16-11-1. * #使用interrupt()中断线程: * <p> * 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它, * 该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是, * 如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。 * </p> */public class InterruptTest {    public static void main(String[] args) {        Thread thread = new Thread(new SubThread());        thread.start();//        try {//            thread.sleep(2000);//        } catch (InterruptedException e) {//            e.printStackTrace();//        }        thread.interrupt(); // 此处会将子线程的休眠中断, 此中断会引发InterruptException, 表示终端        System.out.println("Main exiting");    }}class SubThread implements Runnable {    @Override    public void run() {        System.out.println(Thread.currentThread().getName() + " SubThread >> Sleep 50 seconds.");        try {            Thread.sleep(50000);        } catch (InterruptedException e) { // 处理中断信息            System.out.println(Thread.currentThread().getName() + " handle InterruptedException ");        }        // 继续执行        System.out.println("haha");    }}// output:// Main exiting// Thread-0 SubThread >> Sleep 50 seconds.// Thread-0 handle InterruptedException // haha

使用isInterrupted()方法判断中断状态

可以在Thread对象上调用isInterrupted()方法来检查任何线程的中断状态。这里需要注意:线程一旦被中断,isInterrupted()方法便会返回true,而一旦sleep()方法抛出异常,它将清空中断标志,此时isInterrupted()方法将返回false。

public class InterruptCheck extends Object{      public static void main(String[] args){          Thread t = Thread.currentThread();          System.out.println("Point A: t.isInterrupted()=" + t.isInterrupted());          //待决中断,中断自身          t.interrupt();          System.out.println("Point B: t.isInterrupted()=" + t.isInterrupted());          System.out.println("Point C: t.isInterrupted()=" + t.isInterrupted());          try{              Thread.sleep(2000);              System.out.println("was NOT interrupted");          }catch( InterruptedException x){              System.out.println("was interrupted");          }          //抛出异常后,会清除中断标志,这里会返回false          System.out.println("Point D: t.isInterrupted()=" + t.isInterrupted());      }  }  //isInterrupt=false//isInterrupt=true//isInterrupt=false

使用Thread.interrupted()方法判断中断状态

可以使用Thread.interrupted()方法来检查当前线程的中断状态(并隐式重置为false)。又由于它是静态方法,因此不能在特定的线程上使用,而只能报告调用它的线程的中断状态,如果线程被中断,而且中断状态尚不清楚,那么,这个方法返回true。与isInterrupted()不同,它将自动重置中断状态为false,第二次调用Thread.interrupted()方法,总是返回false,除非中断了线程。

public class InterruptReset extends Object {      public static void main(String[] args) {          System.out.println(              "Point X: Thread.interrupted()=" + Thread.interrupted());          Thread.currentThread().interrupt();          System.out.println(              "Point Y: Thread.interrupted()=" + Thread.interrupted());          System.out.println(              "Point Z: Thread.interrupted()=" + Thread.interrupted());      }  }  //isInterrupt = false//isInterrupt = true  自动重置标志位//isInterrupt = false

待决中断

在上面的例子中,sleep()方法的实现检查到休眠线程被中断,它会相当友好地终止线程,并抛出InterruptedException异常。另外一种情况,如果线程在调用sleep()方法前被中断,那么该中断称为待决中断,它会在刚调用sleep()方法时,立即抛出InterruptedException异常。

public class PendingInterrupt extends Object {      public static void main(String[] args){          //如果输入了参数,则在mian线程中中断当前线程(亦即main线程)          if( args.length > 0 ){              Thread.currentThread().interrupt();          }           //获取当前时间          long startTime = System.currentTimeMillis();          try{              Thread.sleep(2000);              System.out.println("was NOT interrupted");          }catch(InterruptedException x){              System.out.println("was interrupted");          }          //计算中间代码执行的时间          System.out.println("elapsedTime=" + ( System.currentTimeMillis() - startTime));      }  }  

join 和 yield

join方法用线程对象调用,如果在一个线程A中调用另一个线程B的join方法,线程A将会等待线程B执行完毕后再执行。

yield可以直接用Thread类调用,yield让出CPU执行权给同等级的线程,如果没有相同级别的线程在等待CPU的执行权,则该线程继续执行。

0 0
原创粉丝点击