java线程手动销毁_java中如何终止线程的执行

本文介绍了在Java中如何手动销毁线程,包括设置退出标志和调用线程的`interrupt()`方法。当线程在无限循环中执行任务时,可以设置一个volatile布尔变量作为退出标志,当该标志为false时结束循环。此外,通过调用线程的`interrupt()`方法,可以设置线程的中断标识,但需注意在阻塞状态下中断会抛出`InterruptedException`,需要配合退出标志共同使用以避免线程无法终止的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java中如何终止线程的执行

线程被创建后,当run()方法执行完毕,线程便会正常结束和销毁。但是,在有些情况下,run() 方法是永远不会执行完的,比如在run()方法中进行while()轮询任务时,这种情况下就需要我们通过代码手动的退出线程。

这里我们介绍以下几种方法:

1. 使用退出标识

添加一个boolean类型的变量isRun作为线程的退出标识,当isRun为false时,结束循环以中断线程。

public class CloseThread {

public static class CreateThread extends Thread {

//定义退出标志,true一直执行,false退出循环

public volatile boolean isRun = true;

@Override

public void run() {

System.out.println("创建线程完成");

while (isRun) {

System.out.println("工作中..., thread name =" + Thread.currentThread().getName());

SleepUtils.second(1);//线程停止1秒

}

System.out.println("创建执行完毕");

}

public void interrupt() {

System.out.println("中断标识设置为false");

this.isRun = false;

}

}

public static void main(String[] args) {

//实例化一个线程并 start()

Thread thread = new CreateThread();

thread.start();

//线程停止5秒

SleepUtils.second(5);

System.out.println("尝试中断线程");

thread.interrupt();

}

}

执行代码,打印以下结果:

创建线程完成

工作中..., thread name =Thread-0

工作中..., thread name =Thread-0

工作中..., thread name =Thread-0

工作中..., thread name =Thread-0

工作中..., thread name =Thread-0

开始尝试中断线程

中断标识设置为false

线程执行完成

在main()中调用interrupt(),设置线程的中断标识为false,最终成功结束了循环中断了线程的执行。

2. 调用线程本身的interrupt()方法

interrupt()方法是线程本身的一种中断标识,通过调用这个方法可以将线程的isInterrupted()设置为true。

public class CloseThread2 {

public static class CreateThread2 extends Thread {

@Override

public void run() {

while (!currentThread().isInterrupted()) {

System.out.println("工作中...");

}

System.out.println("线程执行完成");

}

}

public static void main(String[] args) {

//实例化一个线程并start()

CreateThread2 thread = new CreateThread2();

thread.start();

//当前线程停止1s

SleepUtils.second(1);

//调用线程的interrupt()

thread.interrupt();

System.out.println("中断线程,thread " + thread.getId() + " :" + thread.isInterrupted());

}

}

执行代码,打印以下结果:

工作中...

工作中...

工作中...

工作中...

工作中...

工作中...

工作中...

工作中...

工作中...

工作中...

中断线程,thread 11 :true

线程执行完成

在main()中调用线程本身的interrupt(),设置线程的中断标识isInterrupted()为true,最终成功结束了循环中断了线程的执行。

但是使用interrupt()时需要注意线程是否处于阻塞状态。当对处于阻塞状态的线程调用interrupt()方法时,会抛出InterruptException异常,而这个异常会清除中断标识,也就是会将中断标识重新修改为false。

我们可以通过以下代码来模拟这种情况:

public class CloseThread3 {

public static class CreateThread3 extends Thread {

@Override

public void run() {

System.out.println("thread 已创建" + currentThread().getId() + " :" + currentThread().isInterrupted());

while (!currentThread().isInterrupted()) {

System.out.println("工作中...");

try {

//线程暂停3秒,模拟处于阻塞状态

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("抛出异常,thread " + currentThread().getId() + " :" + currentThread().isInterrupted());

}

}

System.out.println("线程执行完成");

}

}

public static void main(String[] args) {

CreateThread3 thread = new CreateThread3();

thread.start();

//当前线程暂停5秒

SleepUtils.second(5);

System.out.println("开始尝试中断线程");

//调用线程的interrupt()

thread.interrupt();

System.out.println("中断线程,thread " + thread.getId() + " :" + thread.isInterrupted());

}

}

执行代码,打印以下结果:

thread 已创建11 :false

工作中...

工作中...

开始尝试中断线程

中断线程,thread 11 :false

抛出异常,thread 11 :false

工作中...

java.lang.InterruptedException: sleep interrupted

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

at threadDemo.CloseThread3$CreateThread2.run(CloseThread3.java:15)

工作中...

工作中...

工作中...

.........(不断的打印工作中...)

由此可见,当线程处于阻塞状态中,调用线程的interrupt()将线程的中断标识isInterrupted()设置为,但是当抛出InterruptException异常时,会清除中断标识,将中断标识重新修改为false,导致线程并不会被终止,而是一直执行下去。

为了解决这种情况,我们可以将本文所讲的这两种中断线程的方法组合使用,为线程添加一个中断标识变量,并且重写interrupt()方法:

public class CloseThread4 {

public static class CreateThread4 extends Thread {

//定义退出标志,true会一直执行,false会退出循环

public volatile boolean isRun = true;

@Override

public void run() {

System.out.println("thread 已创建" + currentThread().getId() + " :" + currentThread().isInterrupted());

while (isRun && !currentThread().isInterrupted()) {

System.out.println("工作中...");

try {

//线程暂停3秒,模拟处于阻塞状态

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("抛出异常,thread " + currentThread().getId() + " :" + currentThread().isInterrupted());

}

}

System.out.println("线程执行完成");

}

/**

* 重写interrupt()

*/

@Override

public void interrupt() {

System.out.println("中断标识isRun设置为false");

this.isRun = false;

super.interrupt();

}

}

public static void main(String[] args) {

CreateThread4 thread = new CreateThread4();

thread.start();

//当前线程暂停5秒

SleepUtils.second(5);

System.out.println("开始尝试中断线程");

//调用线程的interrupt()

thread.interrupt();

System.out.println("中断线程,thread " + thread.getId() + " :" + thread.isInterrupted());

}

}

执行代码,打印以下结果:

thread 已创建11 :false

工作中...

工作中...

java.lang.InterruptedException: sleep interrupted

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

at threadDemo.CloseThread4$CreateThread4.run(CloseThread4.java:17)

开始尝试中断线程

中断标识设置为false

中断线程,thread 11 :true

抛出异常,thread 11 :false

线程执行完成

通过自定义中断标识和线程isInterrupted()中断标识组合使用,便解决了线程处于阻塞中调用interrupt()导致isInterrupted()被清除的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值