【问题标题】:Terminated Thread Revival终止线程复兴
【发布时间】:2011-03-23 20:56:30
【问题描述】:

我将一堆线程对象存储在一个数组列表中。我希望能够随机启动这些线程。同一线程可以多次启动。在启动线程对象之前,我会检查线程是否处于活动状态,以及它们是否具有 NEW 或 TERMINATED 状态。这个限制是因为,我不想打扰“忙碌”的线程。现在,对于新线程,这工作正常。但是对于 TERMINATED 线程,我得到一个异常。

当一个线程结束时,它不应该回到“新”状态吗?或者线程是“一次性的”——比如使用一次就完成?

【问题讨论】:

标签: java thread-state


【解决方案1】:

正如Thread.start() 的文档中所说,“多次启动线程是不合法的。特别是,线程一旦完成执行就可能不会重新启动。”

最好保留Runnable 实例并实现自己的逻辑来跟踪每个实例的执行何时完成。使用 Executor 可能是运行 Runnables 的最简单方法。

【讨论】:

    【解决方案2】:

    您可能应该使用java.util.concurrent 中提供的很棒的东西。根据您的描述,ThreadPoolExecutor 听起来不错。

    【讨论】:

      【解决方案3】:

      我就是这样做的

      class GarbageDisposalThread extends Thread {
      public void start() {
         try {
            super.start();
         } catch( IllegalThreadStateException e ) {
            this.arrayList.remove(this);
            this.arrayList.add( new GarbageDisposalThread( this.arrayList ));
         }
      }
      private GarbageDisposalThread() {
      }
      public GarbageDisposalThread( ArrayList<Whatever> arrayList ) {
         this.arrayList = arrayList;
         this.start();
      }
      public void run() {
         // whatever the code
      }
      private ArrayList<Whatever> arrayList = null;
      }
      

      就是这样! 您可以根据需要更改代码:P

      【讨论】:

      • 这实际上是在旧线程的位置创建一个新线程......好吧不是完全就地(但您可以稍微修改代码来做到这一点!)
      【解决方案4】:

      Java 线程无法重新启动。

      来自 javadoc:

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

      有关详细信息,请参阅Thread.start() javadoc。

      还有其他方法可以完成您正在尝试做的事情。例如,您可以使用新线程来继续在已完成执行的线程中完成的工作。您可能还想调查java.util.concurrent package

      【讨论】:

        【解决方案5】:

        从另一个帖子...

        您可以使用 ThreadPoolExecutor,它允许您传入任务并让服务将线程分配给任务。任务完成后,线程进入空闲状态,直到它得到下一个任务。

        因此,您无需重新启动线程,而是重做/恢复任务。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-01-27
          • 1970-01-01
          • 2015-11-22
          • 2014-11-18
          • 2023-03-18
          • 1970-01-01
          相关资源
          最近更新 更多