Java – java线程调用可以多次启动吗?

伙计们,

我知道这个问题在此之前已被提出, 但是间接地 。 但它没有回答我的怀疑。
问题: 在同一个线程上调用start方法两次是否合法?

从规范来看,

不止一次启动线程永远不合法。 特别是,一旦完成执行,线程可能无法重新启动。

我同意。 但是我的代码不会抛出IllegalThreadStateException ,它会在执行以下程序时抛出。

  public class Tester extends Thread { public void run() { System.out.print("run"); } public static void main(String[] args) { Tester thread = new Tester(); new Thread(thread).start(); new Thread(thread).start(); } } 

Q.1)我在Eclipse中运行了上面的代码。 在这里,因为我试图在同一个实例上启动一个新线程,所以应该抛出IllegalThreadStateException。 但事实并非如此。

为什么?

Q.2) 如果我们确实在同一个实例上启动了一个新线程,那会有什么害处?

任何帮助将不胜感激 !

首先,您要调用两个不同的线程对象,即:

  new Thread(thread).start(); new Thread(thread).start(); 

你在两个不同的实例上调用start方法。 因此你没有得到例外。

尝试使用以下来获取exception

 thread.start(); thread.start(); 

对于你的第二个问题。 你可以在这里得到答案: 为什么我们不能在Thread对象的同一个实例上调用两次start方法?

这是幸运的问我:)

你不是在同一个实例上调用start()。 每次使用new时,您都会创建一个独特的实例。 因此调用start()没问题。

如果你这样做:

  Thread t = new Thread(thread); t.start(); t.start(); 

那你可能有问题。

java线程调用可以多次启动吗?

您可以根据需要随时使用start()。 但是,如果在同一个 Thread上多次调用它,您将收到IllegalThreadStateException。

Q.1)我在Eclipse中运行了上面的代码。 在这里,因为我试图在同一个实例上启动一个新线程,所以应该抛出IllegalThreadStateException。 但事实并非如此。

那是因为你创造了三个不同的线程。 一个是测试员,两个包裹测试员。

Q.2)如果我们确实在同一个实例上启动了一个新线程,那会有什么害处?

除了造成混乱,没有。 你不应该这样做。 相反,测试人员应该实现Runnable。

Q.1)我在Eclipse中运行了上面的代码。 在这里,因为我试图在同一个实例上启动一个新线程,所以应该抛出IllegalThreadStateException。 但事实并非如此。

您没有在同一个实例上调用start()。

 new Thread(thread).start(); 

以上陈述与

 new Thread((Runnable)thread).start(); 

在这里,我们看到执行者为何如此有意义。

典型的惯用Java会说你根本不应该运行自己的线程; 创建一个执行程序服务,让它管理线程。 您只需创建Runnable实例并将其传递给执行程序服务; 您可以随时随地调用Runnable的run()方法,无论何时何地都可以这样做,并且您不必在此时关注线程管理。

延伸线程也是一次性交易; 在Java中扩展超类是很昂贵的(因为你获得了一个超类,就是这样)。 但是,您可以根据需要扩展任意数量的接口,因此Runnable也为您提供了更强大的对象层次结构。

因为大多数答案都涵盖了Q1,在这里我想集中讨论Q2,“如果我们确实在同一个实例上开了一个新线程,它会有什么害处?”

要考虑的第一点是你想要第二次调用线程启动方法的时候,是第一个线程执行时(例如:1)还是第一个线程执行完毕后(例2)

case1:识别启动的线程并执行我们唯一的方法是用于创建的线程对象,因此如果有机会第二次调用start()方法,则会假设其他线程被创建并且它执行,但如果我们想要更改/操作在特定实例上执行的多个线程的特定线程,我们将如何单独识别它们,因此完全不可能,因此唯一地识别正在运行的线程并对其进行处理java不允许多次调用start()方法。

情况2:为什么没有java允许我们多次调用start()方法,如果已经运行的线程完成了? 在java中,一旦对象的范围结束,就需要进行垃圾收集,所以在线程对象的情况下也会发生这种情况,但是如果有多次调用start方法的工具,java env不应该允许GC在线程对象认为可能有第二次使用此线程对象,并且此线程对象将永远位于堆(或某个位置)而不会获取GC。

所以考虑到上述两个原因,他们可能只限制了一次调用线程对象上的start()方法。