详解Java停止线程的四种方法

网友投稿 463 2022-10-24


详解Java停止线程的四种方法

一、线程停止基础知识

interrupted(): 测试当前线程是否已经中断。该方法为静态方法,调用后会返回boolean值。不过调用之后会改变线程的状态,如果是中断状态调用的,调用之后会清除线程的中断状态。

isInterrupted(): 测试线程是否已经中断。该方法由对象调用

interrupt(): 标记线程为中断状态,不过不会中断正在运行的线程。

stop(): 暴力停止线程。已弃用。

二、停止线程方法1:异常法停止

线程调用interrupt()方法后,在线程的run方法中判断当前对象的interrupted()状态,如果是中断状态则抛出异常,达到中断线程的效果。

如下示例:

MyThread.java

public class MyThread extends Thread {

@Override

public void run() {

try {

for (int i = 0; i < 500000; i++) {

if (MyThread.interrupted()){

System.out.println("已经是停止状态了,我要退出了!");

throw new InterruptedException();

}

System.out.println("i = " + (i+1));

}

System.out.println("如果我被输出了,则代表线程没有停止");

} catch (InterruptedException e) {

System.out.println("在MyThread类中的run方法中被捕获");

e.printStackTrace();

}

}

}

Main.java

/**

* 根据中断状态退出for循环

* @Author: xjf

* @Date: 2019/5/25 13:27

*/

public class Main {

public static void main(String[] args) {

try {

MyThread myThread = new MyThread();

myThread.start();

Thread.sleep(100);

myThread.interrupt();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("end!");

}

}

结果如下:

i = 19115

i = 19116

i = 19117

i = 19118

i = 19119

end!

已经是停止状态了,我要退出了!

在MyThread类中的run方法中被捕获

java.lang.InterruptedException

 at com.book.interrupt_exit.MyThread.run(MyThread.java:15)

Process finished with exit code 0

三、停止线程方法2:在沉睡中停止

先将线程sleep,然后调用interrupt标记中断状态,interrupt会将阻塞状态的线程中断。会抛出中断异常,达到停止线程的效果。如下示例:

MyThread.java

public class MyThread extends Thread {

@Override

public void run() {

try {

System.out.println("run-----------start");

Thread.sleep(5000);

System.out.println("run-----------end");

} catch (InterruptedException e) {

System.out.println("在沉睡中被停止!进入catch,线程的是否处于停止状态:" + this.isInterrupted());

e.printStackTrace();

}

}

}

Main.java

public class Main {

public static void main(String[] args) {

try {

MyThread myThread = new MyThread();

myThread.start();

Thread.sleep(2000);

System.out.println("状态:"+MyThread.interrupted());

myThread.interrupt();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

结果

run---http://--------start

状态:false

java.lang.InterruptedException: sleep interrupted

在沉睡中被停止!进入catch,线程的是否处于停止状态:false

 at java.lang.Thread.sleep(Native Method)

 at com.book.sleep_interrupt.MyThread.run(MyThread.java:13)

线程先调用interrupt标记中断状态,然后线程再睡眠。会抛出中断异常,达到停止线程的效果。如下:

MyThread1.java

public class MyThread1 extends Thread {

@Override

public void run() {

try {

for (int i = 0; i < 100000; i++) {

System.out.println("i = " + (i+1));

}

System.out.println("run begin");

//interrupt是做一个中断标记,当时不会去中断正在运行的线程,当该线程处于阻塞状态时就会进行中断

//因此,先进行interrupt后,再遇到sleep阻塞时,才会进行中断

Thread.sleep(200000);

System.out.println("run end");

} catch (InterruptedException e) {

System.out.println("先停止,再遇到了sleep! 进入catch!");

e.printStackTrace();

}

}

}

Main1.java

public class Main1 {

public static void main(String[] args) {

MyThread1 myThread1 = new MyThread1();

myThread1.start();

myThread1.interrupt();

System.out.println("end!");

}

}

结果:

i = 99993

i = 99994

i = 99995

i = 99996

i = 99997

i = 99998

i = 99999

i = 100000

run begin

先停止,再遇到了sleep! 进入catch!

java.lang.InterruptedException: sleep interrupted

 at java.lang.Thread.sleep(Native Method)

 at com.book.sleep_interrupt.MyThread1.run(MyThread1.java:19)

四、停止线程方法3:stop()暴力停止

线程调用stop()方法会被暴力停止,方法已弃用。该方法会有不好的后果:

强制让线程停止有可能使一些请理性的工作得不到完成。

对锁定的对象进行了“解锁”,导致数据得不到同步的处理,出现数据不一致的问题(比如一个方法加上了synchronized,并在其中进行了一个长时间的处理,而在处理结束之前该线程进行了stop(),则未完成的数据将没有进行到同步的处理)

五、停止线程方法4:使用return停止线程

调用interrupt标记为中断状态后,在run方法中判断当前线程状态,如果为中断状态则return,能达到停止线程的效果。

备注:建议使用“抛异常”的方法来实现线程的停止,因为在catch块中还可以将异常向上抛,使线程停止的事件得以传播

参考:《Java多线程编程核心技术》


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:时序女神(Horae)不负区块链精神
下一篇:Gworg最低价格通配符SSL不限制子泛域名SSL
相关文章

 发表评论

评论列表