原文来自于:zha-ge.cn/java/64
面试官最爱追问:多线程到底用来干什么?
最近面试了几家公司,感觉面试官们都像集体开了个「多线程灵魂拷问」专题会一样,上来总是:**「你说说,多线程到底用来干啥?」**兄弟我一听,内心疯狂翻白眼。这个问题,听着简单,但真要答全,可不是几句"提高效率"这么潦草。今天想着写一篇小故事,把我和多线程"纠缠半生"的心酸史讲讲,给看官们乐一乐,也许还真能派上用场。
多线程------不是拿来装高大上的
先说实话,刚入行那会儿,我对多线程的理解也就「能同时干好几件事」这么朴素。后来踩过的坑多了,才明白这锅饭根本没那么容易吃。
- 以为多线程就等于速度快?其实火候不对反而慢成🐢。
- 觉得加了线程就能让服务器起飞?很可能一不小心线程打起来服务器趴下。
说白了,多线程是把双刃剑。哪能乱舞呢?得看场景。
那,多线程究竟该用在哪里?
说正事。大厂面试官其实很关心你遇到实际业务场景能不能灵光一现------
常见的合理用法
- 处理高并发请求:比如秒杀、抢票。没法让大家顺序排队慢慢买吧。
- IO密集型任务异步处理:比如给用户发邮件啥的,当然等着有点傻。
- 定时任务&批量任务并发执行:1000个订单要算积分,同步来明天都下班了......
我有次给电商项目做促销,后台要生成一堆优惠券,顺手扔了个线程池。代码看似简单:
java
ExecutorService pool = Executors.newFixedThreadPool(10);
for (Coupon coupon : coupons) {
pool.execute(() -> couponService.generate(coupon));
}
// ...
**说实话,还真快多了。**但谁能想到,第二天运维写信说数据库被打爆,查来查去------都是我这波线程猛男一夜之间把DB压力表干红。
踩坑瞬间
多线程和我最经典的"翻车现场"有如下代表作:
- 忘了同步:多个用户一起抢红包,结果金额成了负数,老板差点报警......
- 线程数无限增长 :Executor写得太潇洒,居然有同事直接用
Executors.newCachedThreadPool()
,后来JVM直接OOM。 - 脏读/死锁:有个方法里 synchronized 写得不明不白,让两个线程互相"拉锯战",程序不报错,就是不动了。
还有一次,想着把计算任务全塞进多线程。写着写着,心里还在偷笑:"我这不是要秒天秒地吗?"
java
synchronized (sharedObj) {
// 关键处理
doImportantStuff();
}
// ...
结果同事打电话过来说:"你这多线程加个 synchronized 是在表演单线程吗?"我:......突然有点尴尬。
经验启示
多年摸爬滚打,关于「多线程到底用在啥时候」我总结了几点"人话版"口诀:
- 别搞事的小场面别瞎开线程。单线程能搞定的事,就别装13。
- 慢的地方优先异步化。比如文件上传、远程接口,IO这种天生慢性子最适合多线程。
- 共享资源先想清楚会不会出事。哪怕有锁,也不一定万无一失。
- 线程不是免费午餐。线程开多了服务器是要"交保护费"的,CPU、内存能吃多少心里要有数。
- 优先用线程池 ,别直接一顿
new Thread()
,后劲你受不了。
最后,面试时如果真被问,甭背八股,结合实际聊聊就好。老板要听你会用,而不是死记原理。