Thread start()和Runnable run()有什么区别?

251

假设我们有这两个Runnables:

class R1 implements Runnable {
    public void run() { … }
    …
}

class R2 implements Runnable {
    public void run() { … }
    …
}

那么这两者有什么区别:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();

    r1.run();
    r2.run();
}

还有这个:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();
    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);

    t1.start();
    t2.start();
}
14个回答

1
如果您直接调用run()方法,则不使用多线程功能,因为run()方法作为调用者线程的一部分执行。
如果您在Thread上调用start()方法,则Java虚拟机将调用run()方法,并且两个线程将同时运行-当前线程(您的示例中的main())和其他线程(您的示例中的Runnable r1)。
请查看start()方法的源代码Thread类
 /**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the <code>run</code> method of this thread.
     * <p>
     * The result is that two threads are running concurrently: the
     * current thread (which returns from the call to the
     * <code>start</code> method) and the other thread (which executes its
     * <code>run</code> method).
     * <p>
     * It is never legal to start a thread more than once.
     * In particular, a thread may not be restarted once it has completed
     * execution.
     *
     * @exception  IllegalThreadStateException  if the thread was already
     *               started.
     * @see        #run()
     * @see        #stop()
     */
    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();

在上面的代码中,您看不到对run()方法的调用。 private native void start0()负责调用run()方法。JVM执行此本地方法。

0
在第一种情况下,您只是调用r1r2对象的run()方法。
在第二种情况下,您实际上正在创建两个新线程! start()将在某个时刻调用run()

7
实际上,start()方法不会调用run()方法:如果它这样做了,那么run()方法将由调用start()方法的同一线程执行。start()方法将创建一个线程,该线程将调用run()方法。 - Bruno Reis

-2
Thread类中独立的start()和run()方法提供了创建线程程序的两种方式。 start()方法启动新线程并调用run()方法,而start()方法立即返回,新线程通常会继续执行,直到run()方法返回。
Thread类的run()方法不做任何事情,因此子类应该覆盖该方法,以在第二个线程中执行代码。如果使用Runnable参数实例化线程,则线程的run()方法会执行新线程中Runnable对象的run()方法。
根据您的线程化程序的性质,直接调用Thread run()方法可能会产生与通过start()方法调用相同的输出,但在后一种情况下,代码实际上在新线程中执行。

2
调用 run() 不是创建线程程序的方法。只有一种方法。 - user207421

-2

Start() 方法调用 Thread 扩展类的 override 方法和实现接口 Runnable 的方法。

但是通过调用 run(),它会搜索 run 方法,但如果类实现了 Runnable 接口,则调用 Runnable 的 override 方法。

ex.:

`

public class Main1
{
A a=new A();
B b=new B();
a.run();//This call run() of Thread because run() of Thread only call when class 
        //implements with Runnable not when class extends Thread.
b.run();//This not run anything because no run method found in class B but it 
        //didn't show any error.

a.start();//this call run() of Thread
b.start();//this call run() of Thread
}

class A implements Runnable{
@Override
    public void run() {
            System.out.println("A ");
    }
}

class B extends Thread {

    @Override
    public void run() {
            System.out.println("B ");
    }
}

`


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接