用run()而不是start()启动一个线程

时间:2014-07-30 12:46:50

标签: java multithreading runnable

我了解到,要启动一个线程,推荐的方法是在线程对象上调用start()方法。但这反过来调用run()方法。那么为什么不直接调用run()方法?

这是我尝试的但是我没有得出任何结论:

public class Tester {
      public static void main (String[] args) {
        Runner r = new Runner();

        Thread t1 = new Thread(r, "Thread A(runnable)");
        Thread t2 = new Thread(r, "Thread B(runnable)");

        Thread s1 = new Strider("Thread C");
        Thread s2 = new Strider("Thread D");

        t1.run(); // t1.start();
        t2.run(); // t2.start();
        s1.run(); // s1.start();
        s2.run(); // s2.start();
      }
    }

    class Runner implements Runnable {
      private int counter;
      public void run() {
        try {
          for (int i = 0; i != 2; i++) {
            System.out.println(Thread.currentThread().getName() + " Runnable: " 
                  + counter++);
            Thread.sleep(1000);
          }
        }
        catch(InterruptedException e) {
          e.printStackTrace();
        }
      }
    }

    class Strider extends Thread {   
      private int counter;
      Strider(String name)    {
        super(name);
      }
      public void run()   {
        try {
          for (int i = 0; i != 2; i++) {
            System.out.println(Thread.currentThread().getName() + ": " 
                + counter++);
            Thread.sleep(1000);
          }
        }
        catch(InterruptedException e)     {
           e.printStackTrace();
        }
      }
    }

OUTPUT(使用start()):变化

Thread A(runnable): 0
Thread C: 0
Thread B(runnable): 1
Thread D: 0
Thread B(runnable): 3
Thread D: 1
Thread A(runnable): 2
Thread C: 1

OUTPUT(使用run()):始终保持不变

main Runnable: 0
main Runnable: 1
main Runnable: 2
main Runnable: 3
main: 0
main: 1
main: 0
main: 1

另外请提供您关于为何不直接使用run()的意见?

2 个答案:

答案 0 :(得分:2)

直接调用run方法不会启动线程,但是像Java中的任何其他方法调用一样是同步调用。因此输出总是保持不变。

只有在调用start方法时,才会涉及实际的Java基础结构,并创建一个新线程,然后调用run方法。

答案 1 :(得分:1)

  

如果显式调用run方法,则不会有新的线程   开始。直接调用run()只是同步执行代码   (在同一个线程中),就像普通的方法调用一样。

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

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