停止线程并再次开始在blackberry中提供IllegalThreadStateException
使用以下代码时,我收到了IllegalThreadStateException
exception:我已经启动了这个线程一次(通过使用thread.start()
)并再次尝试在另一个地方启动它,所以使用下面的代码:
thread.interrupt(); thread.start();
但是thread.start()
抛出了thread.start()
。
我应该用什么来解决它?
Thread
对象只能启动一次。 如果你需要停止/中断一个Thread
,然后想再次启动它,你应该创建一个新实例,并在其上调用start()
:
thread.interrupt(); // if you need to make sure thread's run() method stops ASAP thread = new MyThreadSubclass(); thread.start();
来自API文档
IllegalThreadStateException – 如果线程已经启动。
我知道你不能100%清楚你不能再次调用start()
,即使你之前调用了interrupt()
,但这就是它的工作方式。
如果您查看标准Java的API文档 ,这个问题就更清楚了。
除了Nate的回答。
AnkitRox在评论中说:
谢谢Nate。 我也在尝试你的方法。 但是当时发生的问题是,它为新实例启动了一个新线程,之前的线程也在运行。
所以看起来问题是“线程仍在运行,即使我在其上调用了中断” 。 考虑这个样本(它很难看,但足以显示主要想法):
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
。 就这样。
另一种情况是,如果在调用其中一个抛出InterruptedException
的方法时阻塞线程,则调用interrupt()
,然后该方法将返回抛出InterruptedException
。 如果线程的代码只是“吃掉”那个exception,那么线程仍将继续运行,考虑一个示例:
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
。
在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 );
所以正确的方法应该是定期检查中断的标志 。 如果检测到中断状态,则尽快返回。 另一个常见的选择是根本不使用Thread.interrupt()
,而是使用一些自定义布尔值 。