2011-03-31 61 views
2

民间,Java - java线程可以多次启动吗?

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

spec

这是从来没有的法律,以启动一个线程 不止一次。特别是,一旦 完成执行, 线程可能无法重新启动。

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

任何帮助将不胜感激!

+2

我不认为这只是(它)会造成什么危害的问题。我认为这更多是一个毫无意义的问题。启动一个已经运行的线程是什么意思?你可以开一辆已经开着的汽车吗?这个想法根本没有意义。 – 2011-03-31 14:19:46

回答

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?

这是由我:)幸好问

+0

谢谢。 Q.2有什么想法? – 2011-03-31 14:09:41

9

您不是在同一个实例上调用start()。每次你使用新的你正在创建一个不同的实例。因此调用start()没有问题。

如果你这样做:

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

那么你可能有问题。

+0

+1 ....谢谢!我清除了。 Q.2呢? – 2011-03-31 14:09:14

1

Java线程调用可以开始了不止一次?

您可以根据需要随时参与start()。但是,如果您在相同的线程上多次调用IllegalThreadStateException,则会发生IllegalThreadStateException。

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

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

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

除了造成混淆,没有。你不应该这样做。测试者应该实现Runnable。

1

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

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

new Thread(thread).start(); 

上面的语句是一样的

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

我冒昧地格式化你的答案。我希望这是好的。 – 2011-03-31 14:08:31

+1

@彼得:谢谢 – 2011-03-31 14:09:14

0

在这里,我们看到为什么执行人赚那么多的意义。

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

扩展主题也是一笔交易;在Java中扩展超类很昂贵(因为你得到一个超类,就是这样)。但是,您可以根据需要扩展多个接口,因此Runnable也为您提供了更强大的对象层次结构。

+0

这个答案与我的问题有什么关系? – 2011-03-31 14:13:00

+1

好吧,国际海事组织,你的问题的答案是非常明显的表面上:不,在同一个线程实例上调用start()两次是不合法的。 第一个问题使用了一个无效的假设(你不是在同一个Thread实例上调用两次start(),而是创建了两个单独的Thread实例)。 第二个问题没有实际意义,因为Thread的定义意味着你不能启动两次;你会得到一个非法的状态。 所以**我做的是试图想想你可能试图达到的任务。使用runnables意味着你可以**看起来**运行两次。 – 2011-03-31 15:07:20

0

由于大部分答案都涵盖了Q1,因此我想集中讨论Q2,即“如果我们确实在同一个实例上启动了新线程,它会做什么?”第一个要考虑的问题是第二次调用线程启动方法的时候,第一个线程正在执行(情况:1)还是第一个线程执行完成后(情况2)

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

案例2:如果已经运行的线程完成,java为什么不让我们多次调用start()方法? 在java中,一旦对象的范围结束,它需要被垃圾回收,所以如果线程对象也发生这种情况,但是如果有一个设施可以多次调用start方法,则java env不应该允许GC发生对线程对象认为可能还有第二次使用这个线程对象,并且这个线程对象将永远在堆中(或某个地方)而不会得到GC。

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