- interrupt
向线程发送中断请求,将其中断状态置位true,但是如果这个线程被一些阻塞函数阻塞,sleep,wait,jion等方法阻塞,会抛出InterruptedException。 - interrupted
检测当前线程是否被中断,这是一个静态方法,但是会有一个副作用,强行将现在的线程的中断状态置位为false - isInterrupted
同上面的那个办法,但是不会将中断状态置位为false
public class ThreadTest {
public static void main(String[] args) {
Runnable r=new MyRunable();
Thread t=new Thread(r);
t.start();
//将中断置位为false
t.interrupt();
}
}
class MyRunable implements Runnable{
@Override
public void run() {
try {
for(int i=1;i<100;i++){
//这里第一次输出为true,但是由于interrupted()的特性,将会把当前线程的中断状态置位false。
//所以以后都是false
//如果注释掉这句话,将会抛出异常,因为在中断状态为true时调用sleep和wait方法都会导致线程抛出InterruptedException异常
System.out.println(Thread.interrupted());
//如果调用这句方法将不会当前线程的中断状态置位false。
//同时将上面这句输出注释掉,再删除下面这句话的注释,将会输出ture,抛出异常。
//System.out.println(Thread.currentThread().isInterrupted());
System.out.println(i);
Thread.sleep(200);
}
} catch (InterruptedException e) {
System.out.println("异常出现");
}
}
}
关于中断状态的理解:<以下转自:http://blog.csdn.net/sunxing007/article/details/9123363>
一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果. 所以你看到Thread.suspend, Thread.stop等方法都被Deprecated了.
那么不能直接把一个线程搞挂掉, 但有时候又有必要让一个线程死掉, 或者让它结束某种等待的状态 该怎么办呢? 优雅的方法就是, 给那个线程一个中断信号, 让它自己决定该怎么办. 比如说, 在某个子线程中为了等待一些特定条件的到来, 你调用了Thread.sleep(10000), 预期线程睡10秒之后自己醒来, 但是如果这个特定条件提前到来的话, 你怎么通知一个在睡觉的线程呢? 又比如说, 主线程通过调用子线程的join方法阻塞自己以等待子线程结束, 但是子线程运行过程中发现自己没办法在短时间内结束, 于是它需要想办法告诉主线程别等我了. 这些情况下, 就需要中断.
中断是通过调用Thread.interrupt()方法来做的. 这个方法通过修改了被调用线程的中断状态来告知那个线程, 说它被中断了. 对于非阻塞中的线程, 只是改变了中断状态, 即Thread.isInterrupted()将返回true; 对于可取消的阻塞状态中的线程, 比如等待在这些函数上的线程, Thread.sleep(), Object.wait(), Thread.join(), 这个线程收到中断信号后, 会抛出InterruptedException, 同时会把中断状态置回为false.
public class Thread3 extends Thread{
public void run(){
while(true){
if(Thread.interrupted()){
System.out.println("Someone interrupted me.");
}
else{
System.out.println("Going...");
}
long now = System.currentTimeMillis();
while(System.currentTimeMillis()-now<1000){
// 为了避免Thread.sleep()而需要捕获InterruptedException而带来的理解上的困惑,
// 此处用这种方法空转1秒
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread3 t = new Thread3();
t.start();
Thread.sleep(3000);
t.interrupt();
}
}
下面的程序演示的是子线程通知父线程别等它了:
package test;
public class Test1 extends Thread {
private Thread parent;
public Test1(Thread parent){
this.parent = parent;
}
public void run() {
while (true) {
System.out.println("sub thread is running...");
long now = System.currentTimeMillis();
while (System.currentTimeMillis() - now < 2000) {
// 为了避免Thread.sleep()而需要捕获InterruptedException而带来的理解上的困惑,
// 此处用这种方法空转2秒
}
parent.interrupt();
}
}
public static void main(String[] args){
Test1 t = new Test1(Thread.currentThread());
t.start();
try {
t.join();
} catch (InterruptedException e) {
System.out.println("Parent thread will die...");//此时两个线程在运行
}
}
}