Ank*_*Rox 11 java multithreading blackberry java-me
我IllegalThreadStateException在使用以下代码时遇到异常:我已经启动了这个线程一次(通过使用thread.start())并再次尝试在另一个地方启动它,因此使用以下代码:
thread.interrupt();
thread.start();
Run Code Online (Sandbox Code Playgroud)
但是thread.start()扔了IllegalThreadStateException.
我应该用什么来解决它?
Nat*_*ate 18
Thread对象只能启动一次.如果你需要停止/中断a Thread,然后想再次启动它,你应该创建一个新实例,然后调用start()它:
thread.interrupt(); // if you need to make sure thread's run() method stops ASAP
thread = new MyThreadSubclass();
thread.start();
Run Code Online (Sandbox Code Playgroud)
IllegalThreadStateException - 如果线程已经启动.
我知道start(),即使您之前打过电话,也不能100%明确表示您不能再次打电话interrupt(),但这就是它的工作方式.
除了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
);
Run Code Online (Sandbox Code Playgroud)
注意,即使在interrupt()调用之后线程仍继续运行.产生的输出是:
hi, interrupted = false
hi, interrupted = true
hi, interrupted = true
hi, interrupted = true
...
hi, interrupted = true
Run Code Online (Sandbox Code Playgroud)
实际上,除非有力地关闭,否则程序永远不会停止.那么它的作用是什么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
);
Run Code Online (Sandbox Code Playgroud)
注意,即使在interrupt()调用之后线程仍继续运行.产生的输出是:
hi, interrupted = false
got InterruptedException
hi, interrupted = false
hi, interrupted = false
...
hi, interrupted = false
Run Code Online (Sandbox Code Playgroud)
注意,这次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
);
Run Code Online (Sandbox Code Playgroud)
因此,正确的方法应该是定期检查中断的标志.如果检测到中断状态,则尽快返回.另一个常见的选择是根本不使用Thread.interrupt(),而是使用一些自定义布尔值.