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); } } 

这意味着,您的线程处于其他状态之一, RUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED

您可以通过线程转储或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方法。

然后,它只被调用一次。