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

为什么我们调用start()方法,然后调用run()方法?
我们不能直接打电话run()

请举例说明有什么区别。

不,你不能。 调用run将在同一个线程中执行run()方法,而不会启动新的线程。

为什么我们调用start()方法,然后调用run()方法?

没有那么不准确 start()反过来不会调用run方法。 而是启动执行run方法的线程。 这是本地的。

我们不能直接打电话run()

如果直接调用run() ,则不会启动线程,只需使用相同的调用方法执行该方法即可。

请举例说明有什么区别。

networking上有数百万。 所以我不重复。

实际上, thread.start()创build一个新的线程并有自己的执行场景。

但是thread.run()不会创build任何新线程,而是在当前正在运行的线程中执行run方法。

所以,如果你使用thread.run()那么如果你想只有一个线程执行所有的run方法,那么认为是multithreading的使用。

因为start()不只是调用run()。 它启动一个新的线程,并在该线程中调用run()。

你不能直接运行run()方法。 每当使用thread.start()启动线程时,run()方法就被调用并执行进一步的操作。

主要区别在于,当程序调用start()方法时,会创build一个新的Thread,并在新的Thread中执行run()方法内的代码。如果直接调用run()方法,则不会创build新的Thread,run()在当前线程。

大多数时候调用run()是bug或者编程错误,因为调用者有意调用start()来创build新的线程,这个错误可以被findbugs等许多静态代码覆盖工具检测到。 如果要执行耗时的任务,而不是始终调用start()方法,否则如果直接调用run()方法,则执行耗时任务时主线程将卡住。 Java线程的启动与运行之间的另一个区别是,您不能在线程对象上调用两次start()方法。 一旦启动,第二次调用start()将在Java中抛出IllegalStateException,而您可以调用run()方法两次。

如果直接调用run(),代码将在调用线程中执行。 通过调用start(),一个新的线程被创build,而不是主线程并行执行。

因为start(); 同步并run(); 是简单/常规的方法。 和java一样知道从main();开始执行main(); 方法。 线程知道从run();开始执行run();

这里是Thread类的源代码:

run(); 码:

 @Override public void run() { // overriding from Runnable if (target != null) { target.run(); } } 

start(); 码:

 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(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } } 

简而言之start(); 是线程的pipe理者,如何pipe理等等和run(); 是线程工作的起点。

  1. 为什么我们调用start()方法,然后调用run()方法? 我们不能直接打电话跑()?

调用start() method时,MultiThreading被引入图片中!

调用者线程[主线程]调用run() method ,不涉及新的线程!


  1. 请举例说明有什么区别。

*来源:JDK 1.8 – src代码*

来自Java 8源的可运行接口

可运行界面:

 @FunctionalInterface public interface Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); } 

线程类 – run()方法:

 @Override public void run() { // overriding from Runnable if (target != null) { target.run(); } } 

通过一个简单的Java示例程序来给Marko's Answer提供清晰的信息 :

在调用start()和run()时,看看Thread STATES和Working。

  • 当创build线程t1并调用start()方法时,Thread类( Implements Runnable Interface )的start()方法调用start0()方法,它是一个java本地方法,负责调用Thread类的run()方法在trun中调用目标run()方法。 (这里的目标是ThreadDemo的run()方法)。

  • 直接调用run()方法直接调用一个run()方法,直接由MAIN线程而不是THREAD-2( 它总是处于NEW状态,永远不会进入RUNNABLE状态 )。

     public class ThreadDemo extends Thread { public static void main(String[] args) { ThreadDemo th1 = new ThreadDemo(); // thread t1 will be in NEW state on creation Thread t1 = new Thread(th1); System.out.println("Before Calling start() method :"); System.out.println(t1.getName() +" is in " + t1.getState()+" State\n"); t1.start(); // thread t1 is moved to RUNNABLE state // after calling start() method System.out.println("After Calling start() method :"); System.out.println(t1.getName() +" is in " + t1.getState()+" State\n"); // thread t2 will be in NEW state on creation Thread t2 = new Thread(th1); System.out.println("Before Calling run() method "); System.out.println(t2.getName() +" is in " + t2.getState()+" State\n"); t2.run(); // thread t2 will NOT MOVE to RUNNABLE state // But stay in NEW State after calling run() method // Because it runs of MAIN THREAD's Stack (CALLER THREAD) System.out.println("After Calling run() method "); System.out.println(t2.getName() +" is in " + t2.getState()+" State\n"); } public void run() { // Job to be done by the running Thread System.out.println("JOB in " + Thread.currentThread().getName().toString().toUpperCase()+" Thread's Stack\n"); } 

    }

产量

  Before Calling start() method : Thread-1 is in NEW State After Calling start() method : Thread-1 is in RUNNABLE State JOB in THREAD-1 Thread's Stack Before Calling run() method Thread-2 is in NEW State JOB in MAIN Thread's Stack After Calling run() method Thread-2 is in NEW State 

归属和参考:

  1. Kathy Sierra SCJP 6 [谁跟随这本书写他们的博客也归因于…]
  2. Geeksforgeeks计划[感谢作者]

这是启动方法所做的工作

 synchronized public void start() { //it calls start0() method internally and start0() method does below //create a real child thread and register with thread scheduler //create runtime stack for child thread //call run() on underlying Runtime object }