Java线程是怎么实现run方法的执行的呢?

Java中的线程由java.lang.Thread类表示。当我们创建一个线程并调用其start()方法时,Java虚拟机(JVM)会为该线程分配执行资源并开始执行该线程的run()方法。

以下是Java线程启动和执行run()方法的基本流程:

  1. 创建一个Thread对象或其子类的对象。这通常涉及到定义一个run()方法。
  2. 调用该对象的start()方法。
  3. start()方法通知JVM创建一个新的线程并开始执行。
  4. JVM调用run()方法。

使用流程图表示如下:

sql 复制代码
     +-------------------+
     | Create Thread obj |
     +-------------------+
              |
              v
     +-------------------+
     | Call start()      |
     +-------------------+
              |
              v
     +-------------------+
     | JVM allocates     |
     | execution resources|
     +-------------------+
              |
              v
     +-------------------+
     | JVM calls run()   |
     +-------------------+

重要点:

  • 只有通过调用start()方法,JVM才会为线程分配必要的资源并执行run()方法。直接调用run()方法不会启动新的线程,而只是在当前线程中执行run()方法。
  • 每个Thread对象只能被start()一次。多次调用会抛出IllegalThreadStateException

最佳实践是,不要直接继承Thread类来创建线程,而是实现Runnable接口,并将其传递给Thread的构造函数。这种方法更加灵活,允许你更容易地重用代码和合并资源。


在Java中,主要有两种方法创建多线程:

  1. 继承 Thread:

    • 步骤:

      1. 定义一个类继承Thread类。
      2. 重写run()方法。
      3. 创建该类的实例。
      4. 调用该实例的start()方法。
    • 示例:

      typescript 复制代码
       class MyThread extends Thread {
           public void run() {
               System.out.println("Thread is running");
           }
       }
       ​
       public class Test {
           public static void main(String[] args) {
               MyThread t = new MyThread();
               t.start();
           }
       }
    • 优点:

      • 简单,对于小项目或快速原型设计来说容易实现。
    • 缺点:

      • Java不支持多重继承。如果一个类已经继承了其他类,那么它不能再继承Thread类。
      • 不利于代码复用。继承了Thread类的类只能当作线程使用,而不能当作普通的类使用。
  2. 实现 Runnable 接口:

    • 步骤:

      1. 定义一个类实现Runnable接口。
      2. 重写run()方法。
      3. 创建Thread类的实例,并传入Runnable对象。
      4. 调用Thread实例的start()方法。
    • 示例:

      typescript 复制代码
       class MyRunnable implements Runnable {
           public void run() {
               System.out.println("Thread is running");
           }
       }
       ​
       public class Test {
           public static void main(String[] args) {
               MyRunnable r = new MyRunnable();
               Thread t = new Thread(r);
               t.start();
           }
       }
    • 优点:

      • 更加灵活。由于Java支持多接口继承,所以一个类可以实现多个接口,包括Runnable
      • 更易于代码复用。可以独立于线程机制,作为一个普通的类被复用。
      • 与线程的行为解耦。线程的行为(如优先级、守护状态等)由Thread类控制,任务的行为由Runnable对象控制。
    • 缺点:

      • 需要额外创建Thread对象,这在某些情况下可能会增加轻微的复杂性。

总结:

尽管可以通过继承Thread类来创建线程,但大多数情况下,实现Runnable接口是更好的选择,因为它提供了更大的灵活性和更好的代码复用性。另外,Java提供的Executor框架也推荐使用Runnable或其更灵活的版本,Callable,来定义并行任务。

相关推荐
撸猫7911 小时前
HttpSession 的运行原理
前端·后端·cookie·httpsession
嘵奇2 小时前
Spring Boot中HTTP连接池的配置与优化实践
spring boot·后端·http
子燕若水2 小时前
Flask 调试的时候进入main函数两次
后端·python·flask
程序员爱钓鱼2 小时前
跳转语句:break、continue、goto -《Go语言实战指南》
开发语言·后端·golang·go1.19
Persistence___3 小时前
SpringBoot中的拦截器
java·spring boot·后端
嘵奇3 小时前
Spring Boot 跨域问题全解:原理、解决方案与最佳实践
java·spring boot·后端
景天科技苑5 小时前
【Rust泛型】Rust泛型使用详解与应用场景
开发语言·后端·rust·泛型·rust泛型
lgily-12257 小时前
常用的设计模式详解
java·后端·python·设计模式
意倾城8 小时前
Spring Boot 配置文件敏感信息加密:Jasypt 实战
java·spring boot·后端
火皇4058 小时前
Spring Boot 使用 OSHI 实现系统运行状态监控接口
java·spring boot·后端