面试必考!Java 线程生命周期你真的懂了吗?
面试必考!Java 线程生命周期你真的懂了吗?
说实话,每次面试遇到线程生命周期,我这颗小心脏都忍不住狂跳。同样的题,问了一遍又一遍,可等真要我自己手撸个 Demo 理清楚,emmm,每次都栽在坑里。今天就跟大家唠唠我和 Java 线程生命周期那点“爱恨情仇”,顺便给各位避避坑。
那时候我对线程充满信心
刚入行那会儿,我自信满满,啥线程生命周期图都会画。什么 “新建(New)- 就绪(Runnable)- 运行(Running)- 阻塞(Blocked)- 等待(Waiting)- 超时等待(Timed Waiting)- 死亡(Terminated)”,嘴巴一溜烟背下来,感觉自己要起飞!
我天真地以为:“线程.start() 一下,嘿,就飞起来干活咯!” 但现实就是,用嘴编程,纸上谈兵罢了。毕竟谁没画过那个小连线图呢?
老板让我撸 demo,说好的跑起来就行呢?
有一回,leader 随口丢个需求:
“你把线程几个状态调一遍吧,等会儿面试小伙伴要用。”
听起来很简单对吧?可真动手就发现,线程的那些「待定状态」和「阻塞状态」简直跟猫和老鼠玩捉迷藏!
我一开始憨憨地写了几行代码:
Thread t = new Thread(() -> {
while(!Thread.currentThread().isInterrupted()) {
// 执行任务……
}
});
t.start();
我天真地以为,这不就“运行”了吗?可一到“阻塞”呢?吭哧吭哧看文档,发现只要 sleep()
、wait()
、join()
或者 I/O,都可能进“阻塞”或“等待”状态——这状态名咋这么像,脑壳晕。
踩坑瞬间
踩坑经验来咯,说说我被面试官一顿灵魂拷问的瞬间:
“wait 和 sleep 的区别你真的清楚吗?”
我:
- sleep 我知道,就是线程睡着了嘛。
- wait 好像也是让线程卡住呀?
面试官扶额:
- sleep 不会释放锁,wait 释放锁。
- wait 必须在同步代码块里用,还得配合 notify/notifyAll。
哎,我还真容易搞混。
另外面试官又追问:
“你怎么让线程从 Waiting 变回 Runnable?”
我费劲心思想……原来要 notify()
或 notifyAll()
才能唤醒它。要是用 sleep
,等自个睡醒而已,唤不醒。
代码里乱用,满屏的 IllegalMonitorStateException,简直把我打回原形。
synchronized(obj) {
obj.wait();
// ... 被唤醒,继续走
}
再比如调 join
,线程进入 Timed Waiting(带超时就更复杂),打印状态的时候居然没想象中那么准。
经验启示
喊两句“金句”,自我安慰一波:
-
纸上得来终觉浅,代码调试才知难
别以为背个线程状态图就万事大吉,调一遍才是真的。 -
sleep/wait/join 各有脾气,状态切换别想当然
收好这张小表,别再乱用:
场景 | 会不会释放锁 | 线程状态 |
---|---|---|
sleep |
不释放 | Timed Waiting |
wait |
释放 | Waiting/T.W. |
join |
不释放/部分 | Waiting/T.W. |
- 想让线程苏醒——别忘了 notify,它才是“闹钟”
- 多线程状态靠打印,别光看狗头文档
有空就用t.getState()
打打看,挺有意思!System.out.println(t.getState());
就这样,越折腾越发现:
代码能跑才是硬道理。
下次面试官再问线程状态,我就眯眯眼,浅笑着说:“等我敲给你看哈!”
共同学习,写下你的评论
评论加载中...
作者其他优质文章