Java多线程知识点总结
程序里的 “最小干活单元”(比如 “切菜”“炒菜” 都是一个线程);一个程序同时跑多个 “干活单元”,不用等一个做完再做下一个(比如视频软件同时 “下载视频”+“播放画面”+“发弹幕”)。多个 “干活单元” 同时跑,提高效率;继承 Thread(简单)、实现 Runnable(灵活)、wait/notify(控序);共享资源加锁;新建→就绪→运行→阻塞→终止。
·
一、先搞懂:啥是多线程?
1. 生活例子
- 单线程:你一个人做饭 —— 先买菜→洗菜→切菜→炒菜→洗碗,一步做完才能做下一步(效率低);
- 多线程:你和家人一起做饭 —— 你切菜、妈妈炒菜、爸爸洗碗,同时干活(效率翻倍)。
2. 核心定义
- 线程:程序里的 “最小干活单元”(比如 “切菜”“炒菜” 都是一个线程);
- 多线程:一个程序同时跑多个 “干活单元”,不用等一个做完再做下一个(比如视频软件同时 “下载视频”+“播放画面”+“发弹幕”)。
3. 为啥要用多线程?
- 提高效率:比如下载 3 个文件,单线程要等 1 个下完再下下一个,多线程能同时下;
- 应对多任务:比如游戏里同时 “显示画面”“播放音效”“处理玩家操作”,少一个线程就卡了。
二、多线程的 “核心组件”
1. 线程 “载体”:Thread 类
- 作用:每个线程都是
Thread类的 “具体对象”(就像每个干活的人都是 “人类” 的具体个体); - 必记操作(干活的流程):
new Thread():创建线程(招聘一个人);start():启动线程(让这个人开始干活,底层会自动调用run()方法,千万别直接写run()!);run():线程要做的具体活(比如 “切菜”,需要我们自己写清楚);- 常用小工具:
sleep(1000):让线程休息 1 秒(比如切菜累了,歇 1 秒再切);getName():获取线程名字(比如 “切菜线程”“炒菜线程”);getId():获取线程唯一编号(比如给每个人编个工号)。
2. 任务 “说明书”:Runnable 接口
- 问题:如果一个类已经继承了别的类(比如 “学生类” 继承了 “人类”),就不能再继承
Thread类了(Java 只能单继承); - 解决方案:用
Runnable接口 —— 专门写 “干活的内容”,再交给Thread(人)去执行; - 作用:把 “人” 和 “活” 分开,灵活搭配(比如一份 “洗碗清单”,可以让爸爸做,也可以让妈妈做)。
3. 共享资源 “保护锁”
- 问题:多个线程抢一个资源(比如 3 个人同时用一台冰箱拿东西),会乱套(比如冰箱门被同时拉,东西掉地上)—— 这叫 “线程安全问题”;
- 解决方案:给共享资源 “加锁”,只有拿到钥匙的线程才能用(比如冰箱钥匙只有一把,谁拿到谁用,用完再还回来);
- 用法:简单粗暴,给 “操作共享资源的代码” 套一层
synchronized,比如:

三、多线程 3 种实现方式
1. 方式 1:继承 Thread 类
- 步骤:① 新建类继承
Thread;② 重写run()方法(写干活内容);③ 创建对象,调用start()启动; - 示例(打印 1-5):

2. 方式 2:实现 Runnable 接口
- 步骤:① 新建类实现
Runnable;② 重写run()方法(写干活内容);③ 把这个类的对象传给Thread,调用start(); - 示例(打印 “我在干活”):

3. 方式 3:线程协作
- 场景:比如让线程 1 先打印 1,线程 2 再打印 2,线程 1 再打印 3(之前的交替打印 1-20);
- 核心逻辑:线程之间 “打招呼”—— 该我干就干,不该我干就等着,干完叫下一个;
- 必记方法(必须在
synchronized代码块里用):wait():让当前线程等着(比如线程 2 要打印 2,但现在是 1,就等着);notify():叫醒一个等着的线程(线程 1 打印完 1,叫醒线程 2 打印 2);
- 简单示例(交替打印):


四、线程的 “一生”
- 新建状态(New):
new Thread()—— 刚创建线程,还没启动(像婴儿刚出生,没开始干活); - 就绪状态(Runnable):调用
start()后 —— 线程等着 CPU 分配任务(像成年人等着上班,随时能开工); - 运行状态(Running):CPU 选中线程,执行
run()—— 线程正在干活(像成年人正在上班); - 阻塞状态(Blocked):线程暂停执行(比如
sleep()、wait(),或者等锁)—— 像成年人上班中途休息、等电梯; - 终止状态(Terminated):
run()方法执行完 —— 线程 “下班”,生命周期结束(像成年人退休)。
状态变化图:
新建(new) → 调用start() → 就绪 → CPU 选中 → 运行 → 任务完成 → 终止(运行中可能因sleep()/wait()进入阻塞,阻塞结束后回到就绪)
五、必避的 4 个坑
- 直接调用
run()方法:比如thread.run()—— 这不是启动多线程,只是普通方法调用(相当于让 “人” 拿着清单看一眼,没真干活),必须用start(); - 共享变量不加锁:比如多个线程改同一个
int num—— 会出现 “数字错乱”(比如本来该加 1,结果加了 2),一定要用synchronized锁起来; - 以为线程会按顺序执行:默认情况下,线程执行顺序由 CPU 决定(比如你和妈妈同时干活,谁先做完不一定),想控序必须用
wait/notify; - 死锁:比如线程 A 拿着钥匙 1 等钥匙 2,线程 B 拿着钥匙 2 等钥匙 1—— 互相卡死,程序停住(避免方法:不要让线程互相等对方的锁)。
六、核心总结
- 多线程:多个 “干活单元” 同时跑,提高效率;
- 实现:继承 Thread(简单)、实现 Runnable(灵活)、wait/notify(控序);
- 安全:共享资源加
synchronized锁; - 状态:新建→就绪→运行→阻塞→终止。
更多推荐


所有评论(0)