【问题标题】:When would you call java's thread.run() instead of thread.start()?什么时候调用 java 的 thread.run() 而不是 thread.start()?
【发布时间】:2010-09-20 17:46:09
【问题描述】:

你什么时候会调用 Java 的 thread.run() 而不是 thread.start()

【问题讨论】:

  • 当我是 thread.start() 方法时? :)
  • @blank,答案很简单:t.run()当你想在当前线程上运行t的任务,t.start()当你想运行t的任务在线程 t 本身上。还是您要的是实际用例?
  • 如果你是个白痴,想花一个小时调试多线程代码,后来才意识到你应该调用start()!像我一样...这种方法不应该公开!

标签: java multithreading concurrency


【解决方案1】:

执行thread.run() 不会创建一个新的Thread 来执行您的代码。它只是在调用thread.run() 代码的当前线程中执行代码。

执行thread.start() 会创建一个新的操作系统级线程,其中会调用run() 方法。

本质上:

单线程编程→直接调用run()方法

多线程编程→调用start()方法

此外,正如其他人所提到的,“测试”似乎是您可以直接从代码中调用 run() 的唯一可取情况。

【讨论】:

    【解决方案2】:
    public class TestClass implements Runnable {
        public static void main(String[] args) {
            TestClass tc = new TestClass();
    
            Thread t1 = new Thread(tc);
            System.out.println("Before Starting Thread " + Thread.currentThread().hashCode());
            t1.start();
            System.out.println("After Starting Thread " + Thread.currentThread().hashCode());
        }
    
        @Override
        public void run() {
            System.out.println("TestClass Run method is  Running with thread " + Thread.currentThread().hashCode());        
        }
    }
    

    【讨论】:

    • Hi Frnz,检查并运行上面的示例以清楚地理解第一次运行 t1.start() 并查看哈希码,下次使用 t1.run() 和 chk 哈希码
    • 你的问题在哪里?
    【解决方案3】:

    请注意上述伟大的 cmets:有时您会编写一个使用“start”方法运行不同线程的多线程代码。如果您使用“run”(而不是“start)”进行调试,您会发现它更容易,因为它使代码同步运行并更容易调试。

    【讨论】:

      【解决方案4】:

      Thread 类中单独的start()run() 方法提供了两种创建线程程序的方法。 start() 方法开始执行新线程并调用run() 方法。 start() 方法立即返回,新线程正常继续,直到run() 方法返回。

      Thread 类的run() 方法什么都不做,所以子类应该用代码覆盖该方法,以便在第二个线程中执行。如果使用 Runnable 参数实例化 Thread,则该线程的 run() 方法会改为在新线程中执行 Runnable 对象的 run() 方法。

      根据线程程序的性质,直接调用 Thread run() 方法可以得到与通过 start() 方法调用相同的输出,但在后一种情况下,代码实际上是在新线程中执行的。

      reference

      【讨论】:

      • 与 Tomalak 的回答相同!!如果您从某个地方引用过,请提及!!
      【解决方案5】:

      调用thread.start(),它会依次调用thread.run()。想不出有什么情况你会想绕过thread.start()直接去thread.run()

      【讨论】:

      • 在测试期间是我能想到的唯一合法案例。否则,run() 的内容应该在由 run 或其他方式调用的单独方法中。
      【解决方案6】:

      如果问题是 - “为什么调用线程启动方法而不是直接调用运行方法”,那么我已经用下面的示例代码回答了。希望澄清。 在下面的示例中:

      /*
      By calling t1.start(), 
      we are getting the main calling thread returned immediately 
      after the t1.start() called and is ready to proceed for other 
      operations.And the thread t1 starts executing the run method of the object r. 
      Hence the the output will be:
      
            I am the main thread , i created thread t1 and had it execute run method, which is currently looping from 0 to 1000000
      
            I am done executing run method of testThread
      
      */
      
      
      /* If we call t1.run() instead of t1.start(), (just replace t1.start() with t1.run() in the code for testing)
       its like a regular method call and the main thread will not return until the run method completes, 
       hence the output will be:
      
               I am done executing run method of testThread
      
               I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000
      
      */
      
      
      class testThread implements Runnable{
      
       public void run()
       {
           for(int i=0;i<1000000;i++){} //a simple delay block to clarify.
      
           System.out.println("I am done executing run method of testThread");
      
       }  
      }
      
      public class mainClass{
      
         public static void main(String [] args)
          {
                testThread r = new testThread();
                Thread t1 = new Thread(r);
                t1.start();  /* Question is: can we call instead t1.run() */  
                System.out.println("I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000");
      
          }
      }
      

      【讨论】:

        【解决方案7】:

        这已经被提及了,但要明确一点:创建一个新的 Thread 对象只是为了调用它的 run() 方法是不必要的昂贵并且应该是一个主要的危险信号。创建一个 Runnable impl 并(a)直接调用 it's run() 方法(如果这是所需的行为)或者(b)构造一个新的 Thread 会是一个更好、更解耦的设计可运行并启动线程。

        更好的是,为了进一步解耦,请查看 JDK 5 及更高版本中的Executor 接口和框架。简而言之,这允许您将任务执行(Runnable 实例)与它的执行方式(Executor 实现,它可能在当前线程中执行 Runnable,在一个新线程中,使用来自池的现有线程,等等)。

        【讨论】:

          【解决方案8】:

          至少在 JVM 1.6. 中,有一些检查和 run 被本地调用:

           public synchronized void start() {
                  /**
               * This method is not invoked for the main method thread or "system"
               * group threads created/set up by the VM. Any new functionality added 
               * to this method in the future may have to also be added to the VM.
               *
               * A zero status value corresponds to state "NEW".
                   */
                  if (threadStatus != 0)
                      throw new IllegalThreadStateException();
                  group.add(this);
                  start0();
                  if (stopBeforeStart) {
                  stop0(throwableFromStop);
              }
              }
          
              private native void start0();
          

          【讨论】:

            【解决方案9】:

            假设您知道启动和运行方法的用法,即同步与异步; run 方法可以用来测试功能。

            另外,在某些情况下,同一个线程类可以在两个不同的地方使用同步和异步功能要求,方法是让两个不同的对象分别调用一个 run 方法和另一个 start 方法。

            【讨论】:

              【解决方案10】:

              您可能希望在严格关注功能而非并发性的特定单元测试中调用 run()。

              【讨论】:

                【解决方案11】:

                如果您想像执行任何其他方法一样执行 run() 的内容。当然,不要启动线程。

                【讨论】:

                  【解决方案12】:

                  取自Code Style Java threads FAQ:

                  问:a 之间有什么区别 线程的 start() 和 run() 方法?

                  A: Thread 类中单独的 start() 和 run() 方法提供 创建线程程序的两种方法。 start() 方法启动 执行新线程和调用 run() 方法。 start() 方法 立即返回和新线程 通常会持续到 run() 方法返回。

                  Thread 类的 run() 方法什么都不做,所以子类应该 用代码覆盖该方法 在第二个线程中执行。如果一个 使用 Runnable 实例化线程 参数,线程的 run() 方法 执行 run() 方法 新线程中的可运行对象 而是。

                  根据线程程序的性质,调用 Thread run() 方法可以直接给出 与通过 start() 调用相同的输出 方法,但在后一种情况下 代码实际上是在一个新的 线程。

                  【讨论】:

                  • thread's run() method executes the run() method of the Runnable object in the new thread instead. 这不是真的(或者至少我的 Java 8 源代码另有说明),但不幸的是链接似乎已损坏,所以我在这里报告错误。
                  • @Tomalak,这不能回答所提出的问题。问题不是问区别,而是问我们将调用thread.run()而不是thread.start()的用例。
                  【解决方案13】:

                  当您希望它同步运行时。调用 run 方法实际上不会为您提供多线程。 start 方法创建一个调用 run 方法的新线程。

                  【讨论】:

                    【解决方案14】:

                    从来没有。直接调用 run() 只是同步执行代码(在同一个线程中),就像普通的方法调用一样。

                    【讨论】:

                    • “从不”有点太绝对了。也许并不总是想要一个新线程,并且仍然执行代码?
                    • 也许可以,但在这种情况下,创建一个新线程只是为了调用 run() 方法将是不必要的浪费。最好创建一个 Runnable impl 并在线程内运行它,或者用它构造并启动一个新线程。
                    • 只是重温......如果从来没有,为什么方法是公开的?
                    • 它是公开的,因为 Thread 实现了 Runnable。您可以继承 Thread 并覆盖 run(),这与将代码放入 Runnable 并将其传递给 Thread 构造函数具有相同的效果。不过,最好使用单独的 Runnable 对象,因为这会给您带来更大的灵活性(例如将其传递给 Executor 等)。
                    • 让我举一个我目前正在使用的具体示例:我有一个可以作为 GUI 或命令行运行的程序。在 GUI 的情况下,我希望执行繁重工作的对象在单独的线程上运行并将更新发送到 gui。在命令行模式下,我不需要那个单独的线程。
                    猜你喜欢
                    • 1970-01-01
                    • 2013-02-01
                    • 2014-12-24
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多