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的答案,也可以不添加标志(视情况而定)。然而,在一个系统中,类没有权限中断(很少,但我去过一次),更重要的是,线程尚未启动的边缘情况下,这可能不起作用。