1、使用中断标志位
public class StopThreadTest extends Thread {private boolean exit = false;@Overridepublic void run() {while (!exit) {try {System.out.println("i am running,please wait a moment");Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {try {StopThreadTest threadTest = new StopThreadTest();threadTest.start();Thread.sleep(4000);threadTest.exit = true;} catch (InterruptedException e) {e.printStackTrace();}}
}
2、 使用 interrupt() 中断线程
严格的说,线程中断并不会使线程立即退出,而是给线程发送一个通知,告知目标线程,有人希望你退出了!至于目标线程接收到通知之后如何处理,则完全由目标线程自己决定
线程阻塞状态中如何中断?
public class StopThreadTest{public static void main(String[] args) throws InterruptedException {Thread thread = new Thread() {@Overridepublic void run() {while (true){System.out.println("i am running");try {TimeUnit.SECONDS.sleep(100);} catch (InterruptedException e) {
// this.interrupt();e.printStackTrace();}if (Thread.currentThread().isInterrupted()){System.out.println("i am exit");break;}}}};thread.start();TimeUnit.SECONDS.sleep(1);thread.interrupt();}
}
运行上面的代码,发现程序无法终止
sleep方法由于中断而抛出异常之后,线程的中断标志会被清除(置为false),所以在异常中需要执行this.interrupt()方法,将中断标志位置为true
public class StopThreadTest{public static void main(String[] args) throws InterruptedException {Thread thread = new Thread() {@Overridepublic void run() {while (true){System.out.println("i am running");try {TimeUnit.SECONDS.sleep(100);} catch (InterruptedException e) {this.interrupt();e.printStackTrace();}if (Thread.currentThread().isInterrupted()){System.out.println("i am exit");break;}}}};thread.start();TimeUnit.SECONDS.sleep(1);thread.interrupt();}
}
-
调用线程的interrupt()实例方法,线程的中断标志会被置为true
-
当线程处于阻塞状态时,调用线程的interrupt()实例方法,线程内部会触发InterruptedException异常,并且会清除线程内部的中断标志(即将中断标志置为false)
public class StopThreadTest {/*** 通过interrupt()方式进行中断,同时运用了volatile,保证了flag变量在主线程与T1线程可见性*/public volatile static boolean flag = true;public static class T1 extends Thread {public T1(String name) {super(name);}@Overridepublic void run() {System.out.println("线程 " + this.getName() + " in");while (flag) {}System.out.println("线程 " + this.getName() + " stop");}}public static void main(String[] args) throws InterruptedException {T1 cp = new T1("cp");cp.start();TimeUnit.SECONDS.sleep(1);flag = false;} }