java.lang.IllegalThreadStateException
我正在使用线程。 但是,当我尝试启动一个线程时,我得到一个例外。 具体来说就是java.lang.IllegalThreadStateException。 我的代码是:
public void readCommand() { readThread = new Thread("Thread for reading") { public void run() { while (running) { readBuffer = usbservice.receiveData(); put(readBuffer); } } }; readThread.start(); }
问题是什么?
您将线程存储在字段中。 如果在两个线程中调用该方法,则可以为同一个线程调用readThread.start()
两次。 您需要确保多次调用readCommand,如果已经运行,则可能无法再次启动readThread。 例如,您可以在开始之前同步方法并检查readThread。
如果线程的状态(由Thread.currentThread().getState()
检索的是除NEW
之外的任何东西,则线程将在调用start时抛出exception。
来源;
public synchronized void start() { /* * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); start0(); if (stopBeforeStart) { stop0(throwableFromStop); } }
这意味着,您的线程处于其他状态之一, RUNNABLE
, BLOCKED
, WAITING
, TIMED_WAITING
或TERMINATED
。
您可以通过线程转储或JConsole查看线程的状态,以查看您正在执行的操作。 您可以在调用之前以编程方式获取线程转储,以便start
使用类似tempus-fugit的内容(如果有帮助的话)。
更新:响应你的评论,如果你打断一个线程,在你的情况下,我假设将running
标志设置为false,线程仍将是RUNNABLE
。 要“恢复”线程的工作(再次,我假设你想做的事情),你会再次改变running
标志。 调用start
将失败,因为它已经启动。 你也可以让线程在中断时死掉,然后只需创建一个新的Thread
实例并“启动”那个作为替代。
看一下有关Thread.start()的 oracle文档页面
public void start()
导致此线程开始执行; Java虚拟机调用此线程的run方法。
结果是两个线程同时运行:当前线程(从调用start方法返回)和另一个线程(执行其run方法)。
不止一次启动线程永远不合法。 特别是,一旦完成执行,线程可能无法重新启动。
抛出: IllegalThreadStateException
– 如果线程已经启动。
在multithreading环境中,您必须确保上面的Thread
只启动一次。 如果你在已经启动的Thread
上尝试start()
,你必然会遇到exception。
这很简单:只需使用run()
而不是start()
。
实际上,通话过程是:
-
从main方法:controller.main(usbservice);
-
在控制器对象中:
@Override public void main(Object argv) { if(this.writer == null) this.writer = new CommandWriting(usbservice); if(this.reader == null) this.reader = new CommandReading(usbservice); reader.readCommand(); }
-
在对象阅读器中是readCommand方法。
然后,它只被调用一次。