一、阻塞中断和非阻塞中断
interrupt() 方法并不会立即执行中断操作,这个方法只会给线程设置一个为true的中断标志。
设置之后,则根据线程当前的状态进行不同的后续操作。
(1)如果,线程的当前状态处于非阻塞状态,那么仅仅是线程的中断标志被修改为true而已(2)如果线程的当前状态处于阻塞状态,那么在将中断标志设置为true后,如果是 wait、sleep以及join 三个方法引起的阻塞,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException ,这样受阻线程就得以退出阻塞的状态。
举例:一个线程在运行状态中,其中断标志被设置为true之后,一旦线程调用了wait、join、sleep方法中的一种,立马抛出一个InterruptedException,且中断标志被程序会自动清除,重新设置为false
总结:调用线程类的interrupted方法,其本质只是设置该线程的中断标志,将中断标志设置为true,并根据线程状态决定是否抛出异常。
public class TestThread1 {
public static void main(String[] args) {
MyRunnable1 myRunnable=new MyRunnable1();
Thread thread=new Thread(myRunnable,"子线程");
thread.start();
try{
//主线程休眠
Thread.sleep(3000);
//调用中断,true
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyRunnable1 implements Runnable{
@Override
public void run() {
int i=0;
while(true){
System.out.println(Thread.currentThread().getName()+"循环第"+ ++i+"次");
try{
//判断线程的中断情况
boolean interruptStatus=Thread.currentThread().isInterrupted();
System.out.println(Thread.currentThread().getName()+"循环第"+ ++i+"次"+interruptStatus);
Thread.sleep(1000);
//非阻塞中断 只是设置标记位true
//非阻塞中断 只是设置标记位true
if(interruptStatus){
//如果中断为true则退出
break;
}
} catch (InterruptedException e) {
// 一个线程在运行状态中,其中断标志被设置为true之后,一旦线程调用了
// wait、join、sleep方法中的一种,立马抛出一个InterruptedException,且中断标志被程序会自动清除,重新设置为false
System.out.println("阻塞中断"+Thread.currentThread().isInterrupted());//显示false并抛异常
return;//不想返回还可继续写代码
}
}
}
}
子线程循环第1次false
子线程循环第2次false
子线程循环第3次false
阻塞中断false
二、stop方法停止
由于不安全,已经不使用了,因为stop会解除由线程获取的所有锁定,当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止,假如一个线程正在执行:synchronized void { x = 3; y = 4;} 由于方法是同步的, 多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x = 3;时,被调用了 stop()方法,即使在同步块中,它也会马上stop了,这样就产生了不完整的残废数据。
三、设置标记位停止
public class TestThread2_1 {
public static void main(String[] args) throws InterruptedException {
MyThreads my = new MyThreads();
new Thread(my, "线程A").start();
Thread.sleep(10000);
//设置标记位
//my.setFlag(false);
//stop方法
new Thread(my, "线程A").stop();
System.out.println("代码结束");
}
}
class MyThreads implements Runnable {
private boolean flag = true;
@Override
public void run() {
int i = 1;
while (flag) {
try {
Thread.sleep(1000);
System.out.println("第" + i + "次执行,线程名称为:" + Thread.currentThread().getName());
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}