假设我们有两个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();
}

当前回答

第一个例子:没有多线程。两者都在单个(现有)线程中执行。没有线程创建。

R1 r1 = new R1();
R2 r2 = new R2();

r1和r2只是实现Runnable接口并因此实现run()方法的类的两个不同对象。当你调用r1.run()时,你是在当前线程中执行它。

第二个例子:两个独立的线程。

Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);

t1和t2是Thread类的对象。当调用t1.start()时,它会启动一个新线程,并在内部调用r1的run()方法以在该新线程中执行它。

其他回答

如果直接调用run(),它将在调用线程上执行,就像任何其他方法调用一样。需要thread .start()来实际创建一个新线程,以便并行执行可运行对象的run方法。

区别在于,当程序调用start()方法时,将创建一个新线程,run()方法中的代码将在新线程中执行:而如果直接调用run()方法,则不会创建新线程,run()方法中的代码将直接在当前线程中执行。

Java线程中start()和run()的另一个区别是不能调用start()两次。一旦启动,第二次start()调用将在Java中抛出IllegalStateException,而您可以多次调用run()方法,因为它只是一个普通的方法。

如果直接调用run()方法,则没有使用多线程特性,因为run()方法是作为调用者线程的一部分执行的。

如果你在线程上调用start()方法,Java虚拟机将调用run()方法,两个线程将并发运行——当前线程(在你的例子中是main())和其他线程(在你的例子中是Runnable r1)。

看看线程类中的start()方法的源代码

 /**
     * 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()方法的调用。

私有本机void start0()负责调用run()方法。JVM执行这个本机方法。

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

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

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

调用run()在调用线程上执行,就像任何其他方法调用一样。而thread. start()创建一个新线程。 调用run()是一个编程错误。