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

时间:2011-03-31 14:02:02

标签: java multithreading

伙计,

我知道此前已经提出过这个问题,虽然是间接的。但它没有回答我的疑问 问题:Is it legal to call the start method twice on the same Thread?

来自spec

  

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

我同意。但是我的代码没有抛出一个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)如果我们确实在同一个实例上开了一个新线程,会有什么害处?

非常感谢任何帮助!

6 个答案:

答案 0 :(得分:9)

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

如果你这样做了:

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

然后你可能有问题。

答案 1 :(得分:6)

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

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

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

尝试使用以下来获取异常

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

第二个问题。你可以在这里得到答案:Why can't we call the start method twice on a same instance of the Thread object?

幸运地问我:)

答案 2 :(得分:1)

  

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

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

  

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

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

  问:2)如果我们确实在同一个实例上开了一个新线程,它会有什么害处?

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

答案 3 :(得分:1)

  

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

你不是在同一个实例上调用start()。

new Thread(thread).start();

以上陈述与

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

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

由于大部分答案都涵盖Q1,所以我想集中讨论第二季度的问题。如果我们确实在同一个实例上开了一个新线程,它会有什么害处?"

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

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

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

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