Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我们调用Thread.start()方法,而Thread.start()方法反过来又调用run方法?_Java_Multithreading - Fatal编程技术网

Java 为什么我们调用Thread.start()方法,而Thread.start()方法反过来又调用run方法?

Java 为什么我们调用Thread.start()方法,而Thread.start()方法反过来又调用run方法?,java,multithreading,Java,Multithreading,为什么我们要调用线程对象的start()方法,该方法依次调用run()方法,为什么不直接调用run()方法 […]为什么不直接调用run()方法? run()方法只是一个普通方法(由您重写)。与任何其他普通方法一样,直接调用它将导致当前线程执行run() 所有的魔法都发生在start()内部。start()方法将导致JVM生成一个新线程,并使新生成的线程执行run()我猜您正在谈论启动一个线程。如果是这种情况,那么您不直接调用run方法的原因是您将调用该方法,而不是启动线程 若直接调用run()

为什么我们要调用线程对象的
start()
方法,该方法依次调用
run()
方法,为什么不直接调用
run()
方法

[…]为什么不直接调用run()方法?

run()
方法只是一个普通方法(由您重写)。与任何其他普通方法一样,直接调用它将导致当前线程执行
run()


所有的魔法都发生在
start()
内部。
start()
方法将导致JVM生成一个新线程,并使新生成的线程执行
run()

我猜您正在谈论启动一个线程。如果是这种情况,那么您不直接调用run方法的原因是您将调用该方法,而不是启动线程

若直接调用run()方法,则其主体将在当前线程的上下文中执行。调用
start()
方法时,将创建一个新线程,并在此新线程中执行
run()
方法。

Runnable
只是一个接口。实现
Runnable
的类没有什么特别之处,它只有一个
run
方法

Thread#start
是一个本机实现的方法,它创建一个单独的线程并调用
Thread
run
方法,在新线程中执行代码

线程
实现
可运行
run
的代码如下所示:

@Override
public void run() {
    if (target != null) {
        target.run();
    }
}
如果
Thread
实例是通过将
Runnable
传递给
Thread
的构造函数而创建的,则调用
Runnable
run
方法

否则,扩展
Thread
的类必须重写
run
方法才能使
start
工作


Thread
上调用
run
不会创建新线程。

如果需要,我们可以调用
run()
方法,但如果调用run方法,它将像普通Java方法一样运行。尽管我们称之为
start(
)它,
JVM
创建一个新线程,run方法将在该线程上执行

为什么我们要调用thread对象的start()方法,该方法依次调用 run()方法


不,没有
start()
调用操作系统,该操作系统启动一个新线程,该线程(为了大大简化)调用
run()
方法。同时,
start()
方法已经返回给它的调用者。它们不是等价的。

即使我们没有以编程方式创建任何线程,对于每个应用程序,O.S都会创建一个默认线程,用CPU执行其代码

直接调用run方法将使该run方法在O.S.给定的主线程中执行

但创建线程类的目的是确保run方法在不同的线程中执行。除非O.S的线程管理器创建一个线程,否则您的run方法将不会在单独的线程中执行。要请求O.S创建单独的线程,必须调用start()方法,该方法将向O.S发送创建线程的请求。一旦O.S创建了一个线程,那么O.S将在新创建的线程上下文中自动调用线程类的run方法。因此,您创建单独线程并在单独线程中执行run方法的目的将得到满足

若您直接调用run方法,那个么就好像O.S并没有为您创建任何线程,默认的主线程将执行您的run方法。 没有必要为此创建单独的线程类

希望我清楚。如果你需要更多的解释来回答你的问题,请告诉我


注意:尽管书上说JVM创建线程,但JVM内部必须向O.S层的线程管理器驱动程序发送请求,以便在其线程池中创建新线程。这就是为什么我在这里更多地使用O.s术语而不是JVM。

如果线程已实例化但未启动,则称其处于新状态
除非在线程实例上调用start()方法,否则它不会被称为活动。
如果在新创建的线程实例上不调用start()方法,线程将被视为不活动。
如果未调用start()方法,而在线程实例上直接调用run()方法,run()方法中的代码不会在单独的新线程中运行,但会在现有线程中开始运行

查看示例中的问题

class Multi extends Thread{  
 public void run(){  
  for(int i=1;i<5;i++){  
    try{Thread.sleep(500);}catch(InterruptedException e){System.out.println(e);}  
    System.out.println(i);  
  }  
 }  
 public static void main(String args[]){  
  Multi t1=new Multi();  
  Multi t2=new Multi();  

  t1.run();  
  t2.run();  
 }  
}  

Output:1
       2
       3
       4
       5
       1
       2
       3
       4
       5
类多扩展线程{
public void run(){

对于(inti=1;i当我们使用start方法时,将创建一个新线程,然后为每个新线程执行run方法中的代码

使用start方法为每个线程创建两个堆栈:堆栈和本机堆栈

但是
Run
方法调用只执行
execute
方法中的代码,因为Run方法调用不会创建不同的堆栈

范例

import java.util.concurrent.TimeUnit;

public class thread implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        Thread gg=new Thread(new thread());
        Thread gg1=new Thread(new thread());
        gg.run();
        gg1.start();
        /*gg.start();
        gg1.start();*/

    }

    @Override
    public void run() {
        for(int i=0;i<5;i++)
        {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        System.out.println("Hello..." + i);
        }

    }

}
import java.util.concurrent.TimeUnit;
公共类线程实现可运行{
/**
*@param args
*/
公共静态void main(字符串[]args){
线程gg=新线程(新线程());
线程gg1=新线程(新线程());
gg.run();
gg1.start();
/*gg.start();
gg1.start()*/
}
@凌驾
公开募捐{
for(int i=0;i
start()
run()
方法用于运行线程。
run()
方法只是一个普通方法,它由用户重写,并将在当前线程上调用。
start()
方法间接运行
run()
方法并创建一个新线程。

区别在于,如果我们通过
start()
方法执行run方法,它将创建一个新线程,我们可以在其中执行run方法,否则
run()
 /**
     * 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();