我们可以直接调用run()方法代替在Java中调用start()方法吗?

时间:2020-01-09 10:35:06  来源:igfitidea点击:

如果在Java线程上直接调用run()方法而不是调用start()方法,那是一个非常常见的采访问题。这篇文章详细讨论了为什么需要调用start()方法以及直接调用run()方法会发生什么情况。

需要调用start()方法

当我们使用Java创建线程并调用其start()方法时,该线程被安排为运行(处于Runnable状态)。底层操作系统的调度程序调度可运行线程运行(通过分配CPU周期),然后只有JVM调用线程的run()方法。

因此,开发人员不会直接调用run()方法,但这并不意味着我们不能直接调用run()方法。让我们看看如果直接用Java调用run()方法会发生什么。

直接调用run()方法会发生什么

如果直接调用run()方法而不是遵循调用start()方法的约定,则实际上不会启动任何新线程。我们在run()方法中编写的逻辑将在当前线程的上下文中执行,当前线程很可能是主线程。

因此,如果不调用线程的start方法,而直接调用run()方法,则不会产生新线程,并且run()方法将作为正常的重写方法运行。

Java示例代码

在示例代码中,创建了两个线程,然后直接调用run()方法,因为未调用start()方法,因此将在当前线程的上下文中依次执行run方法。我们可以在输出中看到没有并发执行,因为两个线程依次调用了run()方法,还请注意线程名称即主线程。

public class MyThread implements Runnable {
  @Override
  public void run() {
    System.out.println("In run method " + "Thread Name - " 
      + Thread.currentThread().getName());
    for(int i = 0; i < 5 ; i++){
      System.out.println("i - " + i);
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }      
    }
  }

  public static void main(String[] args) {
    Thread t1 = new Thread(new MyThread());
    Thread t2 = new Thread(new MyThread());
    
    /*t1.start();
    t2.start();*/

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

输出:

In run method Thread Name - main
i - 0
i - 1
i - 2
i - 3
i - 4
In run method Thread Name - main
i - 0
i - 1
i - 2
i - 3
i - 4

调用start()方法而不是直接调用run()方法时的示例相同。我们可以在输出中看到线程正在同时执行。还要注意现在的线程名称,这些名称现在是已创建线程的名称。

public class MyThread implements Runnable {
  @Override
  public void run() {
    System.out.println("In run method " + "Thread Name - " 
      + Thread.currentThread().getName());
    for(int i = 0; i < 5 ; i++){
      System.out.println("i - " + i);
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }      
    }
  }
	
  public static void main(String[] args) {
    Thread t1 = new Thread(new MyThread());
    Thread t2 = new Thread(new MyThread());

    t1.start();
    t2.start();
  }
}

输出:

In run method Thread Name - Thread-0
In run method Thread Name - Thread-1
i - 0
i - 0
i - 1
i - 1
i - 2
i - 2
i - 3
i - 3
i - 4
i - 4