当我使用以下代码时,我会遇到 IllegalThreadStateException
异常:
我已经通过使用 thread.start()
启动了这个线程一次,并且现在在另一个地方尝试再次启动它,所以使用了以下代码:
thread.interrupt();
thread.start();
但是thread.start()
抛出了IllegalThreadStateException
。
我应该使用什么来解决它?
当我使用以下代码时,我会遇到 IllegalThreadStateException
异常:
我已经通过使用 thread.start()
启动了这个线程一次,并且现在在另一个地方尝试再次启动它,所以使用了以下代码:
thread.interrupt();
thread.start();
但是thread.start()
抛出了IllegalThreadStateException
。
我应该使用什么来解决它?
Thread
对象只能被启动一次。如果您需要停止/中断一个 Thread
,然后再次启动它,您应该创建一个新实例,并在其上调用 start()
:
thread.interrupt(); // if you need to make sure thread's run() method stops ASAP
thread = new MyThreadSubclass();
thread.start();
API文档中指出,如果线程已经启动,则会抛出IllegalThreadStateException异常。
如果您之前调用了interrupt()方法,即使这样仍然不能再次调用start(),这一点可能并不完全清楚,但事实就是如此。
如果您查看标准Java的API文档,则这个问题就更加明确了。
interrupt()
会抛出任何异常。但是我猜测你在第一次运行此代码之前就调用了interrupt()
。只有在线程已经启动一次后才需要中断线程。所以,在第二次、第三次等想要调用start()
的时候,你可以在调用start()
之前立即调用interrupt()
。你可以在调用thread.interrupt()
之前测试thread.isAlive()
。如果这不起作用,你需要展示更多的代码(例如,如何创建Thread对象)。 - NateAsyncUploadQuestionsAndLeads
,它是由Thread
扩展而来的。通过以下方式初始化线程对象:AsyncUploadQuestionsAndLeads uploadThread = new AsyncUploadQuestionsAndLeads(event);
并从其他地方启动线程:
uploadThread.start();
一段时间后,我使用以下代码:
uploadThread.interrupt(); uploadThread.start();
这是我遵循的代码过程。还有一个问题是-当线程完成其运行块时,它是否会自行停止? - AnkitRoxinterrupt()
,然后立即调用start()
。如果您要第二次调用start()
,则必须再次使用uploadThread = new AsyncUploadQuestionsAndLeads(event)
创建一个新实例。是的,在run()
方法完成后,线程基本上会停止。在run()
完成后,您不能在同一实例上再次调用start()
。您必须创建一个新的实例。 - Natefinal Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
for (int i = 0; i < 100000000; i++); // simulate some action
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
interrupt()
,线程仍然会继续运行。产生的输出如下:hi, interrupted = false
hi, interrupted = true
hi, interrupted = true
hi, interrupted = true
...
hi, interrupted = true
interrupt()
有什么作用呢?它只是将中断标志设置为true
。在调用interrupt()
后,Thread.currentThread().isInterrupted()
开始返回false
。就是这样。InterruptedException
的方法之一的调用时调用interrupt()
,那么该方法将返回并抛出InterruptedException
。如果线程的代码只是“吃掉”了该异常,那么线程仍然会继续运行,考虑下面的示例:final Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("got InterruptedException");
}
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
请注意,即使调用了 interrupt()
方法,线程仍然会继续运行。以下是产生的输出:
hi, interrupted = false
got InterruptedException
hi, interrupted = false
hi, interrupted = false
...
hi, interrupted = false
interrupt()
,interrupted=false
。这是因为每当捕获到InterruptedException
时,中断标志会被重置为false
。final Thread t = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("we've been interrupted");
// restore the interrupted flag
Thread.currentThread().interrupt();
}
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
因此,正确的方法是定期检查中断标志。如果检测到中断状态,则立即返回。另一个常见选项是根本不使用Thread.interrupt()
,而是使用一些自定义布尔值。
java
标签,因为它适用于任何java
相关内容。 - Vit Khudenko