java 如何杀线程_关于java:我怎么能杀死一个线程?

本文深入探讨了Java中线程中断的实现方式及其最佳实践。通过示例代码讲解了如何利用线程中断来优雅地终止线程执行,以及如何避免常见的陷阱。

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

Thread currentThread=Thread.currentThread();

public void run()

{

while(!shutdown)

{

try

{

System.out.println(currentThread.isAlive());

Thread.interrupted();

System.out.println(currentThread.isAlive());

if(currentThread.isAlive()==false)

{

shutdown=true;

}

}

catch(Exception e)

{

currentThread.interrupt();

}

}

}

});

thread.start();

你能检查一下上面的代码并帮我把线程终止吗

请参阅本文forward.com.au/javaprogramming/howtostopathread.html

看看杀死javame 1.2线程的最佳实践?也许有帮助。

呃…这甚至是可编译的代码吗?

根据定义,Thread.currentThread().isAlive()永远不可能是错误的。这个代码毫无意义。

调用stop的另一种方法是使用interrupt向线程发出信号,您希望它完成正在执行的操作。(这假定您要停止的线程行为良好,如果它忽略了InterruptedExceptions,在抛出后立即吃掉它们,并且不检查中断状态,那么您将返回到使用Stop()的状态)。

下面是我为一个线程问题编写的一些代码,它是线程中断如何工作的一个示例:

public class HelloWorld {

public static void main(String[] args) throws Exception {

Thread thread = new Thread(new Runnable() {

public void run() {

try {

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

Thread.sleep(5000);

System.out.println("Hello World!");

}

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}

});

thread.start();

System.out.println("press enter to quit");

System.in.read();

thread.interrupt();

}

}

需要注意的一些事情:

中断会导致sleep()和wait()立即抛出,否则你会被困在等待睡眠时间过去。

请注意,不需要单独的布尔标记。

被停止的线程通过检查中断状态和捕获while循环之外的interruptedExceptions(使用它退出循环)进行协作。中断是一个可以使用异常进行流控制的地方,这就是它的全部意义。

在catch块中的当前线程上设置中断在技术上是最好的做法,但对于本例来说,这是多余的,因为没有其他任何东西需要设置中断标志。

关于已发布代码的一些观察:

发布的示例不完整,但将对当前线程的引用放入实例变量中似乎是一个坏主意。它将被初始化为创建对象的任何线程,而不是执行run方法的线程。如果在多个线程上执行同一个可运行实例,那么实例变量在大多数情况下不会反映正确的线程。

检查线程是否处于活动状态必然会导致"真"(除非当前线程实例变量引用错误的线程时出现错误),只有在线程执行完毕后,Thread#isAlive才为"假",不会因为线程被中断而返回"假"。

调用Thread#interrupted将导致清除中断标志,在这里没有意义,特别是因为返回值被丢弃。调用Thread#interrupted的目的是测试中断标志的状态,然后清除它,这是一种方便的方法,用于抛出InterruptedException的对象。

@内森+1,如果我看到这个答案,我甚至不会费心写我自己的答案!GG

首先,此代码假定将使用睡眠或其他可中断的阻塞调用。情况不必如此。代码可以做一些复杂的计算。使用线程中断需要更多的注意。一些IOS也可以中断,如果有多个这样的IOS,我们可能需要仔细清理对象,等等。我建议一般使用一个标志变量作为一个更安全的选项。

@Raze:仅仅捕获阻塞I/O中断和中断当前线程就足够了吗?

它肯定会使线程停止,但这在run()方法中是:{ try { while(...) {byte[] input = getChunkFromNetworkWhichHasCriticalData(); alertUser(input); } } catch(ClosedByInterruptException cbie) {...} }的。两点:不是所有的IO调用都被中断,所以它可能永远不会退出。如果调用将中断的IO调用,那么处理部分获取的数据可能会很困难。在许多情况下,像视频流一样,这不是一个问题。如果代码中有多个可中断点,它可能会变得更加复杂。

@拉兹:护理是绝对需要的。这就是为什么我将thread.currentThread().interrupt()留在示例中,以演示是否维护了中断标志。在任何情况下,为了操作的目的,我不认为标志是必要的,尽管它不会损害任何东西,并且您的示例得到了很好的实现。

要点是:1.代码中必须有可中断的调用。2。如果处理部分运行/获取/发送的代码/数据很重要,则必须仔细设计代码。当不需要这种中断和中断处理时,可以避免这种情况。但在许多情况下,建议正确地使用中断,而且效率更高。

@greeshma引用的例子中没有睡眠,我也没有做任何假设。此外,我还见过我认识的人用多线程实现音频多路转换,使用中断退出,在某些情况下无法刷新音频缓冲区,这会留下一小部分音频循环,直到程序退出。

@格雷:修好了,谢谢

@灰色:>>再试一次

内森看起来不错。谢谢。

@内森休斯,我看到了你的回答,这很有帮助,只是我不明白为什么在接球时再次打电话打断对方?为什么同一线程调用会再次中断?

@阿比迪:在这种情况下,这并不重要。如果您有嵌套的组件,所有组件都必须响应中断,那么您需要这样做以确保每个人都看到中断。

这是一个很好的答案!我总是实现一个单独的标志,但这更有意义。就正确关闭资源而言,这不是线程问题,而是错误处理问题。IO应该在finally块中关闭,而不是try或catch块。这经常是混乱的JDK7出来的Try with Resources语句。

通常,线程在中断时终止。那么,为什么不使用本机布尔值呢?尝试isInterrupted():

Thread t = new Thread(new Runnable(){

@Override

public void run() {

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

// do stuff

}

}});

t.start();

// Sleep a second, and then interrupt

try {

Thread.sleep(1000);

} catch (InterruptedException e) {}

t.interrupt();

+1,人们喜欢自己滚动(布尔值),但你必须使它易变和布拉布拉布拉布拉…使用标准中断策略(如IsInterrupted)感觉更优雅:d

如果我调用threat.interrupt();而不调用thread.sleep(1000),会发生什么,这安全吗?

@ lovekushvishwakarma docs.oracle.com javase 10 / / / / / Java API文档/蓝/ hellip &;

最好的方法是使用一个布尔标志来向线程发送信号。

class MyRunnable implements Runnable {

public volatile boolean stopThread = false;

public void run() {

while(!stopThread) {

// Thread code here

}

}

}

创建一个名为myUnnable的myUnnable实例,将其包装在新的Thread实例中并启动该实例。如果要将线程标记为停止,请将myUnnable.StopThread设置为true。这样,它就不会停在某个东西的中间,只会停在我们期望它停下来的地方。

如果与阻塞队列相结合,使用标志取消可能很危险。

@卢克,你说的是线程可能因为排队而无法退出的情况吗?

是的,基本上,如果您有一个阻塞操作,比如queue.put在while循环中,并且您的队列已满,并且队列的所有使用者都已完成,那么即使您设置了停止任务的标志,也不会完成任务。

@Luke,这对于任何使用object.wait的操作或许多NIO调用中的一个都是正确的,在这种情况下,可以使用Nathan的答案,也可以不添加标志(视情况而定)。然而,在一个系统中,类没有权限中断(很少,但我去过一次),更重要的是,线程尚未启动的边缘情况下,这可能不起作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值