java多线程之——停止线程多种方式
原文地址:
Java的中断机制使用一个中断变量作为标识,假如某个线程的中断变量被标记为true,那么这个线程在适当的时机会抛出异常,程序员捕获异常后进行相应的处理。要玩转线程中断,首先必须明白中断标识是如何检测和触发的。
中断标识方式🍊
针对“正在运行”的线程😎
java层自定义
package com.thread.threadSafe.stop; /** * @program: thread * @author: xmonster_大魔王 * @create: 2022-09-20 19:15 * 在Java层自定义中断标识 **/ public class InterruptThreadDemo extends Thread{ private volatile boolean isInterrupted = false; public void customInterrupt(){ isInterrupted = true; } @Override public void run() { while (!isInterrupted){ System.out.println("我在跑!!"); } System.out.println("我被打断啦!!"); } public static void main(String[] args) { InterruptThreadDemo threadDemo = new InterruptThreadDemo(); threadDemo.start(); try { Thread.sleep(100); }catch (InterruptedException e){ } threadDemo.customInterrupt(); } }
使用JVM提供的中断标识
package com.thread.threadSafe.stop; /** * @program: thread * @author: xmonster_大魔王 * @create: 2022-09-20 19:15 * 在Java层自定义中断标识 **/ public class InterruptThreadDemo2 extends Thread{ @Override public void run() { while (!Thread.interrupted()){ System.out.println("我在跑!!"); } System.out.println("我被打断啦!!"); } public static void main(String[] args) { InterruptThreadDemo2 threadDemo = new InterruptThreadDemo2(); threadDemo.start(); try { Thread.sleep(100); }catch (InterruptedException e){ } threadDemo.interrupt(); } }结果和上面一样
阻塞/等待状态中断方式🍉
对于可以运行的线程,我们需要通过while的形式来检测中断标识,而对于本身已经处于阻塞/等待状态的线程,则无需自己检测中断标识,我们要做的就是捕获中断异常并进行处理。😎
这里需要注意的就是:sleep会清除中断状态睡眠
package com.thread.threadSafe.sleep.stop; /** * @program: thread * @author: xmonster_大魔王 * @create: 2022-09-19 22:08 **/ public class MyThread extends Thread{ @Override public void run() { super.run(); try { System.out.println("run begin"); Thread.sleep(2000); System.out.println("run end"); }catch (InterruptedException e){ System.out.println("在沉睡中被停止!进入了catch!!!!"+this.isInterrupted()); e.printStackTrace(); } } /** * run begin * main end!! * 在沉睡中被停止!进入了catch!!!!false * java.lang.InterruptedException: sleep interrupted * at java.base/java.lang.Thread.sleep(Native Method) * at com.thread.threadSafe.sleep.stop.MyThread.run(MyThread.java:15) * 如果线程在sleep方法中被打断,那么线程会进入catch语句,并且清除停止状态,变成false * 注意:这里是先sleep(),再interrupt() * 最终的结论:不管这两个方法谁先执行,只要是他们两个方法碰一起了,就必定会出现异常 */ }Run方法
package com.thread.threadSafe.sleep.stop; /** * @program: thread * @author: xmonster_大魔王 * @create: 2022-09-19 22:09 **/ public class Run { public static void main(String[] args) throws InterruptedException { try { MyThread myThread = new MyThread(); myThread.start(); Thread.sleep(200); myThread.interrupt(); }catch (InterruptedException e){ System.out.println("main catch"); e.printStackTrace(); } System.out.println("main end!!"); } }运行结果
其他的经典情景🍍
如果线程既可能处于可执行状态、又可能处于阻塞/中断状态,怎么处理?
这里其实就是对上面两个方法进行一个“综合”🥪
🥝既要有通过while循环来判断是否中断,在这个while循环中,线程还可能进入睡眠状态,睡眠状态是由JVM层面去支持中断的,所以当这个线程调用了中断方法之后,它会中断睡眠并抛出中断异常
🥑还记得上面说过的一个注意点吗,sleep捕获了异常之后它会清除中断标识,然后抛出异常,因为这个中断标识会被清除掉,所以我们要再次设置一下中断标识,不然上面的while循环跳不出来啦package com.thread.threadSafe.stop; /** * @program: thread * @author: xmonster_大魔王 * @create: 2022-09-21 10:02 **/ public class RunningWatingInterrupt { public static void main(String[] args) { Thread thread = new Thread(() -> { while (!Thread.currentThread().isInterrupted()){ System.out.println("running..."); try { Thread.sleep(200); }catch (InterruptedException e){ System.out.println(Thread.currentThread().isInterrupted()); Thread.currentThread().interrupt(); System.out.println("thread has stoped!"); } } }); thread.start(); try { Thread.sleep(2000); }catch (InterruptedException e){ e.printStackTrace(); } thread.interrupt(); } }
park的特殊中断
实际上通过park方式阻塞线程,它的终端方法比较特殊,这种阻塞方式下的中断不会抛出中断异常,但是中断标识会被设置成true,不会清除这个中断标识。
package com.thread.threadSafe.stop; import java.util.concurrent.locks.LockSupport; /** * @program: thread * @author: xmonster_大魔王 * @create: 2022-09-21 10:30 **/ public class park { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println("i am running!!"); LockSupport.park(); //关键点 }); thread.start(); try { Thread.sleep(2000); }catch (InterruptedException e){ e.printStackTrace(); } thread.interrupt(); System.out.println(thread.isInterrupted()); } }
其它参考地址:




浙公网安备 33010602011771号