首页 文章

Thread start()和Runnable run()之间的区别是什么

提问于
浏览
196

假设我们有这两个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 回答

  • 60

    First example: 没有多线程 . 两者都在单个(现有)线程中执行 . 没有线程创建 .

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

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

    Second example: 两个单独的线程 .

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

    t1t2 是类 Thread 的对象 . 当你调用 t1.start() 时,它会启动一个新线程并在内部调用 r1run() 方法在该新线程中执行它 .

  • 2

    如果你只是直接调用 run() ,它就会在调用线程上执行,就像任何其他方法调用一样 . 需要 Thread.start() 来实际创建一个新线程,以便并行执行runnable的 run 方法 .

  • 29

    区别在于 Thread.start() 启动一个调用 run() 方法的线程,而 Runnable.run() 只调用当前线程上的 run() 方法 .

  • 281

    difference 是当程序调用 start() 方法时,创建 new 线程并且 run() 中的代码在 new 线程中执行,而如果直接调用 run() 方法,将创建 no new thread并且 run() 内的代码将直接在当前线程中执行 .

    Java线程中 start()run() 之间的另一个 difference 是你 can not 两次调用 start() . 一旦启动,第二次 start() 调用将在Java中抛出 IllegalStateException ,而您可以多次调用 run() 方法,因为它只是一个 ordinary 方法 .

  • 3

    实际上 Thread.start() 创建了一个新线程并拥有自己的执行场景 .

    Thread.start() 异步调用 run() 方法,这会将新Thread的状态更改为Runnable .

    Thread.run() 不会创建任何新线程 . 相反,它同步执行当前运行线程中的run方法 .

    如果您使用的是 Thread.run() ,那么您根本就没有使用多线程的功能 .

  • 1

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

  • -2

    如果在main方法中执行 run() ,则main方法的线程将调用 run 方法而不是运行所需的线程 .

    start() 方法创建新线程,并且必须为其执行 run() 方法

  • 21

    Thread.start() 代码使用调度程序注册线程,调度程序调用 run() 方法 . 此外, Thread 是类,而 Runnable 是接口 .

  • 8

    大多数这些答案都错过了大局,就Java语言而言, t.start()r.run() 之间的区别与其他两种方法之间没有区别 .

    他们都只是方法 . 它们都在调用它们的线程中运行 . 他们都做了他们编码做的任何事情,然后他们都在同一个线程中返回给他们的呼叫者 .

    最大的区别是 t.start() 的大多数代码都是本机代码,而在大多数情况下, r.run() 的代码将是纯Java . 但是's not much of a difference. Code is code. Native code is harder to find, and harder to understand when you find it, but it'仍然只是代码告诉计算机该做什么 .

    那么, t.start() 做什么?

    它创建一个新的本机线程,它安排该线程调用 t.run() ,然后它告诉操作系统让新线程运行 . 然后它返回 .

    r.run() 做了什么?

    有趣的是,提出这个问题的人是写这个问题的人 . r.run() 做任何你(即编写它的开发人员)设计它做的事情 .


    t.start() 是库为您的代码在需要新线程时调用的方法 .

    r.run() 是您为库在新线程中调用提供的方法 .

  • 5

    成员们提出的要点是正确的,所以我只想添加一些内容 . 问题是JAVA不支持多继承 . 但是,如果你想从另一个A类派生一个B类,但是你只能从一个Class派生出来 . 现在的问题是如何从两个类“派生”:A和Thread . 因此,您可以使用Runnable接口 .

    public class ThreadTest{
       public void method(){
          Thread myThread = new Thread(new B());
          myThread.start;
       }
    }
    
    public class B extends A implements Runnable{...
    
  • -1

    如果直接调用 run() 方法,则表示您没有使用自 run() 方法作为调用者线程的一部分执行以来的多线程功能 .

    如果在Thread上调用 start() 方法,Java虚拟机将调用run()方法,并且两个线程将同时运行 - 当前线程(在您的示例中为 main() )和其他线程(在您的示例中为Runnable r1 ) .

    看看Thread classstart() 方法的源代码

    /**
         * 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执行此本机方法 .

  • 6

    在第一种情况下,您只是调用 r1r2 对象的 run() 方法 .

    在第二种情况下,你实际上创建了2个新线程!

    start() 会在某个时候调用 run()

  • 4

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

    但是通过调用run()它会搜索run方法但是如果类实现了Runnable接口,那么它调用Run()的run()覆盖方法 .

    例:

    `

    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 ");
        }
    }
    

    `

  • 85

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

    Thread类的run()方法不执行任何操作,因此子类应该使用代码覆盖该方法以在第二个线程中执行 . 如果使用Runnable参数实例化Thread,则线程的run()方法将在新线程中执行Runnable对象的run()方法 .

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

相关问题