我使用下面的代码时,得到IllegalThreadStateException
例外: 我已经开始这个线程一次(使用thread.start()
),并再次试图在另一个地方启动它,因此使用下面的代码:停止线并重新开始给IllegalThreadStateException黑莓
thread.interrupt();
thread.start();
但thread.start()
抛出IllegalThreadStateException
。
我应该用什么来解决它?
我使用下面的代码时,得到IllegalThreadStateException
例外: 我已经开始这个线程一次(使用thread.start()
),并再次试图在另一个地方启动它,因此使用下面的代码:停止线并重新开始给IllegalThreadStateException黑莓
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();
IllegalThreadStateException - 如果线程已经启动。
我知道这是不是100%清楚,你不能再打电话start()
,即使您以前叫interrupt()
,但是这是它的工作方式。
如果你看看API docs for standard Java,这个问题更加清楚。
谢谢Nate。但是当我试图使用'thread.interrupt();' 它再次显示异常为 - ** IllegalThreadStateException **。 – AnkitRox
@AnkitRox,API文档不显示'interrupt()'抛出任何异常。不过,我猜测你甚至在第一次运行这段代码之前就调用了interrupt()。你真的只需要中断线程,如果它已经启动一次。所以,你想调用'start()'的第二,第三等时间,你可以事先调用'interrupt()'。你可以在调用'thread.interrupt()'之前测试'thread.isAlive()'。如果这不起作用,则需要显示更多代码(例如,如何创建Thread对象)。 – Nate
我有一个类'AsyncUploadQuestionsAndLeads',它由'Thread'扩展。 使用初始化Thread对象: 'AsyncUploadQuestionsAndLeads uploadThread =新AsyncUploadQuestionsAndLeads(事件);' 而从其他地方启动线程: 'uploadThread.start();' 一段时间后,我使用代码如下: 'uploadThread.interrupt(); uploadThread.start();' 这是我遵循的代码过程。 还有一个问题是 - 当线程完成它的运行块时线程是否自行停止? – AnkitRox
除了Nate的回答。
在他的评论AnkitRox状态:
感谢奈特。我也在尝试你的方法。但那时发生的问题是,它为新实例启动了一个新线程,并且之前的线程也在工作。
所以看起来这个问题是“线程仍在运行,即使我呼吁它的中断”。考虑这个样本(这是丑陋的,但足以显示其主要思想):
final 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
。就这样。
另一种情况是,如果interrupt()
被称为同时线程被阻塞在抛出InterruptedException
,则该方法将返回投掷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
注意,此时interrupted = false
interrupt()
被称为甚至后。这是因为每当InterruptedException
被捕获时,中断标志被重置为false
。
在Java中停止线程是合作机制。这意味着如果没有线程本身的合作,就无法完成。下面是上述样品的固定的版本:
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
);
所以,正确的做法应该是定期检查中断标志。如果检测到中断状态,则只需返回ASAP。另一个常见选项是根本不使用Thread.interrupt()
,但是some custom boolean instead。
很好的解释。并不丑陋:) – Nate
刚刚添加了'java'标签,因为它对任何'java'都很常见。 –