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();
是线程工作的起点。
- 为什么我们调用start()方法,然后调用run()方法? 我们不能直接打电话跑()?
调用
start() method
时,MultiThreading被引入图片中!调用者线程[主线程]调用
run() method
,不涉及新的线程!
- 请举例说明有什么区别。
*来源: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
归属和参考:
- Kathy Sierra SCJP 6 [谁跟随这本书写他们的博客也归因于…]
- 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 }