Java多线程编程:基于Thread类创建线程详解
在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 不利于区分不同功能的线程。可以通过以下两种方式定制名称:
- 通过构造函数指定:在子类中添加带有 name 参数的构造方法,并在内部调用
super(name)。 - 使用 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:MyThread1thread2:MyThread2thread3:Thread-1(注意索引号取决于前面已经分配的序号)
注意事项与潜在风险
- 线程名的确定性:
start()前后均可调用setName(),但在多线程并发环境下,如果在start()之后、且run()方法内部依赖当前线程名,可能会导致竞态条件。建议在调用start()之前完成所有的初始化设置。 - 避免重复启动:每个 Thread 实例的
start()方法只能被调用一次。如果尝试对已启动过的线程再次调用start(),将抛出IllegalThreadStateException异常。
总结
通过继承 Thread 类是 Java 入门多线程的基石。理解构造器传参与 setName 的区别,并能正确处理主线程与子线程的关系,是构建稳定并发应用的前提。以上就是 Java 基于 Thread 类创建线程的详细教程,更多关于 Java 并发编程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









