Java多线程编程:基于Thread类创建线程详解

山间有风
山间有风
发布时间:2026-10-14| 6人浏览过
原创

在Java中,通过继承 java.lang.Thread 类并覆盖 run() 方法是启动多线程的传统且基础的途径。本文将深入剖析 Thread 类的实例化方式、构造函数的各个参数含义、线程命名的最佳实践,以及 start() 调用的关键规则。

Thread 类的构造函数与核心参数

要使用 Thread 类建立线程,必须实例化 Thread 或其子类。Thread 类提供了多个重载的构造函数以适应不同的需求,其核心参数如下:

  • Runnable target:目标线程对象。值得注意的是,由于 Thread 类本身实现了 Runnable 接口,因此可以直接传入自身实例。
  • String name:线程的名称。若不在此处指定,系统会自动分配默认名称(如 Thread-0),该名称随线程创建顺序递增。
  • ThreadGroup group:线程所属的线程组。未指定时,线程将被加入默认的线程组。
  • long stackSize:线程栈的大小。通常建议为 CPU 页面大小的整数倍,例如在 x86 平台下默认通常为 12KB 左右。

第 1 步:继承 Thread 类并覆盖 run 方法

目的:定义线程的执行逻辑

一个普通的 Java 类只要继承 Thread 类,就可以成为线程类。真正的业务代码必须包裹在覆盖父类的 run() 方法中。当调用 start() 时,JVM 会启动新的执行流并自动回调该方法。

代码如下:
package mythread;
public class Thread1 extends Thread {
    @Override
    public void run() {
        // 输出当前正在执行的线程的名字
        System.out.println(this.getName());
    }

    public static void main(String[] args) {
        // 1. 获取主线程名
        System.out.println(Thread.currentThread().getName());

        // 2. 实例化两个自定义线程
        Thread1 thread1 = new Thread1();
        Thread1 thread2 = new Thread1();

        // 3. 启动线程
        thread1.start();
        thread2.start();
    }
}

结果观察与说明

运行上述代码的典型输出顺序可能为:

  • main:这是 JVM 启动时自动创建的主线程名称。
  • Thread-0 / Thread-1:分别是 thread1 和 thread2 被赋予的系统默认名称。

结论:任何 Java 程序至少拥有一个名为 main 的主线程。只有当显式创建了额外的线程实体,才构成了真正的多线程环境。

第 2 步:灵活设置与修改线程名

目的:提高调试可读性

默认生成的 Thread-N 不利于区分不同功能的线程。可以通过以下两种方式定制名称:

  1. 通过构造函数指定:在子类中添加带有 name 参数的构造方法,并在内部调用 super(name)。
  2. 使用 setName 方法:在线程实例化后,通过调用 setName(String name) 进行修改。
代码如下:
package mythread;
public class Thread2 extends Thread {
    private String who; // 用于标识线程身份的业务字段

    public Thread2(String who) {
        super();       // 调用无参构造,使用默认线程名
        this.who = who;
    }

    public Thread2(String who, String name) {
        super(name);   // 通过超类设置指定的线程名
        this.who = who;
    }

    @Override
    public void run() {
        // 打印身份标识和当前的系统线程名
        System.out.println(who + ":" + this.getName());
    }

    public static void main(String[] args) {
        // 1. thread1 在构造时指定名称 "MyThread1"
        Thread2 thread1 = new Thread2("thread1", "MyThread1");

        // 2. thread2 仅指定业务标识,稍后手动改名
        Thread2 thread2 = new Thread2("thread2");
        thread2.setName("MyThread2"); // 动态设置线程名

        // 3. thread3 既无构造参数也未手动改名
        Thread2 thread3 = new Thread2("thread3");

        // 启动所有线程
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

运行结果分析

可能的输出:

  • thread1:MyThread1
  • thread2:MyThread2
  • thread3:Thread-1 (注意索引号取决于前面已经分配的序号)

注意事项与潜在风险

  • 线程名的确定性:start() 前后均可调用 setName(),但在多线程并发环境下,如果在 start() 之后、且 run() 方法内部依赖当前线程名,可能会导致竞态条件。建议在调用 start() 之前完成所有的初始化设置。
  • 避免重复启动:每个 Thread 实例的 start() 方法只能被调用一次。如果尝试对已启动过的线程再次调用 start(),将抛出 IllegalThreadStateException 异常。

总结

通过继承 Thread 类是 Java 入门多线程的基石。理解构造器传参与 setName 的区别,并能正确处理主线程与子线程的关系,是构建稳定并发应用的前提。以上就是 Java 基于 Thread 类创建线程的详细教程,更多关于 Java 并发编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。