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,来定义并行任务。

相关推荐
程序员岳焱33 分钟前
Java 与 MySQL 性能优化:Java 实现百万数据分批次插入的最佳实践
后端·mysql·性能优化
麦兜*1 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构
大只鹅1 小时前
解决 Spring Boot 对 Elasticsearch 字段没有小驼峰映射的问题
spring boot·后端·elasticsearch
ai小鬼头1 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
IT_10242 小时前
Spring Boot项目开发实战销售管理系统——数据库设计!
java·开发语言·数据库·spring boot·后端·oracle
bobz9652 小时前
动态规划
后端
stark张宇3 小时前
VMware 虚拟机装 Linux Centos 7.9 保姆级教程(附资源包)
linux·后端
亚力山大抵3 小时前
实验六-使用PyMySQL数据存储的Flask登录系统-实验七-集成Flask-SocketIO的实时通信系统
后端·python·flask
超级小忍4 小时前
Spring Boot 中常用的工具类库及其使用示例(完整版)
spring boot·后端
CHENWENFEIc4 小时前
SpringBoot论坛系统安全测试实战报告
spring boot·后端·程序人生·spring·系统安全·安全测试