Java:多线程
·
一、前置基础:进程与线程核心概念
1. 进程
程序的一次运行过程,系统资源分配的最小单位;每个进程有独立内存空间,进程间资源不共享。
2. 线程
进程内部的独立执行路径,CPU 调度的最小单位;一个进程至少有 1 个主线程(main 线程);同一进程下多个线程共享堆内存、方法区,只独占栈内存。
3. 并发 & 并行
- 并发:同一时间段,多个线程交替抢占 CPU 执行(单核 CPU 本质是并发)。
- 并行:同一时刻,多个线程同时在多核 CPU 分别执行。
二、线程创建方式一:继承 Thread 类
1. 实现步骤(标准四步)
- 自定义类 继承 Thread 父类
- 重写 run () 方法:封装线程要执行的任务逻辑
- 创建自定义线程类实例对象
- 调用 start () 方法 启动线程,而非直接调用 run ()
2. 继承结构图示
java.lang.Thread 抽象父类
↑
自定义线程类 (extends Thread)
重写 run() 作为线程执行入口
3. 完整标准代码
// 1. 自定义线程类,继承Thread
public class MyThread extends Thread {
private int flag;
// 构造方法传参,区分不同线程任务
public MyThread(int flag) {
this.flag = flag;
}
// 2. 重写run方法:线程真正执行的任务体
@Override
public void run() {
if (flag == 1) {
for (int i = 0; i < 10; i++) {
System.out.println("线程1执行:" + i);
}
System.out.println("线程1任务结束");
} else {
for (int i = 0; i < 10; i++) {
System.out.println("线程2执行:" + i);
}
System.out.println("线程2任务结束");
}
}
}
三、线程启动规则与测试代码
1. 测试启动类
public class ThreadTest {
public static void main(String[] args) {
// 3. 创建线程对象
MyThread t1 = new MyThread(1);
MyThread t2 = new MyThread(2);
// 4. 调用start() 开启新线程
t1.start();
t2.start();
// 主线程独立执行,和子线程并发
System.out.println("主线程main执行完毕");
}
}
2. 核心硬性规则
-
run () 只是普通成员方法直接调用
t1.run()不会开启新线程,只是普通串行执行,依旧在 main 线程中运行。 -
start () 是开启线程唯一方式
- start () 是 native 本地方法,底层向 JVM 申请开辟新栈内存
- 由 JVM 自动回调 run () 方法,真正实现多线程并发
-
一个线程对象只能调用一次 start ()重复调用会直接抛出:
IllegalThreadStateException非法线程状态异常。 -
Java 单继承局限一旦继承 Thread 类,无法再继承其他任意父类,程序扩展性被限制。
四、多线程执行核心特性
-
抢占式调度机制CPU 时间片随机分配,哪个线程抢到资源就先执行,人为无法控制执行顺序。
-
并发执行、互不阻塞main 主线程、子线程 1、子线程 2同时交替运行,彼此不会互相等待。
-
执行结果无序每次运行控制台打印顺序都不一样,由操作系统 CPU 调度策略决定。
-
主线程退出不影响子线程main 主线程执行结束退出,子线程会继续走完自己的任务,不会随主线程消亡。
-
线程默认命名规则未手动设置名称时,默认:
Thread-0、Thread-1、Thread-2……可用getName()获取线程名,setName("线程名")自定义命名。
五、重点辨析:run () 与 start () 深度对比
表格
| 对比维度 | run () 方法 | start () 方法 |
|---|---|---|
| 方法类型 | 普通成员方法 | native 本地方法 |
| 作用 | 封装线程任务逻辑 | 向 JVM 申请创建新线程 |
| 是否开新线程 | 不开启,普通串行执行 | 开启独立新线程 |
| 执行方式 | 手动直接调用 | JVM 自动回调 run () |
| 调用次数 | 可无限重复调用 | 只能调用一次,多次抛异常 |
六、继承 Thread 类 优缺点完整总结
优点
- 写法简单直观,入门容易。
- 自定义类直接继承 Thread,可直接调用 Thread 类所有通用方法(sleep、getName、setName 等)。
缺点
- 受 Java单继承机制限制,不能再继承其他业务类。
- 线程和任务耦合在一起,线程对象和业务逻辑绑定,不方便复用。
- 多个线程任务代码冗余,无法共享同一个任务资源。
- 实际开发中极少使用,一般优先用 Runnable、Callable、线程池。
七、补充必考易错点
- 不要把 循环、耗时操作 写在 main 主线程,应放到子线程 run () 中。
- 多线程无序不是代码问题,是CPU 抢占式调度的正常特性。
- 只有调用 start () 才会开辟独立栈内存,run () 只是普通方法调用,无新栈。
- 线程生命周期:新建状态 → 就绪状态 → 运行状态 → 阻塞 / 终止状态。
更多推荐

所有评论(0)