【问题标题】:Starting a single thread again after the work is done工作完成后再次启动单个线程
【发布时间】:2014-12-03 19:49:22
【问题描述】:

我创建了一个线程,一个方法会调用这个线程到.start(),这个方法可能会在线程完成它的工作之前再次调用。

我在run() 中添加了一个return;,所以当它完成它的工作并重新启动时它会死掉。但是当我在它的工作完成后尝试启动它时,它给了我一个IllegalThreadStateException。线程没有关闭吗?我以为添加 return; 会关闭它。

【问题讨论】:

  • A Thread object 与线程不同。在您调用.start() 之前,不会创建实际线程。它会做它所做的事情,然后在.run() 方法返回或抛出异常之后不再存在。 Thread 类的设计者希望确保每个Thread 对应一个,并且只对应一个线程。由于一个线程只运行一次然后不复存在,因此对于任何给定的Thread 对象t,只允许您调用一次t.start() 是有道理的。
  • @jameslarge - 为什么要在评论中留下答案?

标签: java multithreading


【解决方案1】:

来自Javadoc:

使该线程开始执行; Java虚拟机调用该线程的run方法。

结果是两个线程同时运行:当前线程(从调用 start 方法返回)和另一个线程(执行它的 run 方法)。

多次启动一个线程是不合法的。特别是,线程一旦完成执行就可能不会重新启动。

抛出: IllegalThreadStateException - 如果线程已经启动。

仔细看最后两句,你会找到答案的。

【讨论】:

    【解决方案2】:
    When you wish to stop the thread, you set this flag and call join() on the thread and wait for it to finish.
    

    来自How to properly stop the Thread in Java?

    Thread 对象只能启动一次。如果你需要 停止/中断一个线程,然后想重新启动它,你应该 创建一个新实例,并在其上调用 start():

    thread.interrupt();  // if you need to make sure thread's run() method stops ASAP
    thread = new MyThreadSubclass();
    thread.start();
    

    来自Stop thread and again start giving IllegalThreadStateException in blackberry

    【讨论】:

      【解决方案3】:

      您不能对同一个 Thread 对象多次调用 start。如果您有一些工作需要不时在单独的线程上完成多次,但还必须在运行之间存储状态,那么您可以实现Runnable 而不是Thread(假设您正在这样做) .之后,当您需要再次执行工作时,您可以将相同的 Runnable 实例传递给新的 Thread 对象,然后在新的 Thread 对象上调用 start()。

      【讨论】:

      • 一个每次创建一个新线程来执行后台任务的应用程序,是一个急需线程池的应用程序(例如,Executors.newFixedThreadPool()) .创建和销毁线程的成本很高,如果应用程序对可以同时启动的后台线程数没有上限,这也是有风险的。
      • 我同意。但我在这里的建议是可以通过最小的变化(几行)来获得至少有效的东西。从长远来看,重构为更好的多线程结构是最好的方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-03
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      • 2017-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多