好吧,请各位,我问这问题是一个安卓问题,但我意识到我能够在纯Java上重新创建类似的场景。
我创建了一个线程类作为内部类,并重写了它的run()方法
Thread aaa = new Thread(){
public void run() {
for(int i=0;i<5;i++){
System.out.println(getId()+" <-"+i);
try {
Thread.sleep(1000 * 1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
};在我的主要方法中,我启动了线程,然后睡了6秒(这个想法是线程将在主醒过来时完成它的运行方法),然后我尝试再次启动相同的线程。
public static void main(String[] args) {
Test test = new Test();
//Start the thread
test.aaa.start();
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Start same dead thread again
test.aaa.start();
}在我的Ubuntu机器上,再次启动线程,在最后一行给出IllegalThreadStateException,这就是我所认为的规范。输出情况如下:
9 <-0
9 <-1
9 <-2
9 <-3
9 <-4
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:708)
at Test.main(Test.java:15)但是在我的Android设备上,它又一次运行相同的线程,输出看起来就像:
50023 <-0
50023 <-1
50023 <-2
50023 <-3
50023 <-4
50023 <-0
50023 <-1
50023 <-2
50023 <-3
50023 <-4我不明白同样的线程是如何重新启动的,至少Id证明了这一点。
发布于 2021-02-13 06:12:53
我认为您之所以感到困惑,是因为您正在两个相似但不相同的运行时环境上进行测试。换句话说,这里有两个不同的运行时环境或虚拟机(又称虚拟机):
您描述的第二次thread.start()调用导致IllegalThreadStateException的行为是基于JVM的标准Java运行时环境中的正确行为。
您正在体验的代码不会在设备上崩溃的行为是因为您的安卓设备上的Java运行时环境是不同的--它不完全符合JVM规范。
发布于 2021-02-13 06:32:02
根据Java规范,您只能启动一个线程一次。换句话说,您不能启动已经启动的线程。
它碰巧适用于Android (或其他任何地方)这一事实与此无关。即使它看起来有效,它仍然是错误的,它可能导致不可预测的结果。
如果需要再次运行线程,请创建一个新线程。
作为一种替代,您可以使用ExecutorService,但这是一个不同的主题。
https://stackoverflow.com/questions/66182154
复制相似问题