多线程啊,说出来你可能不信,它比我家猫抢沙发还难控制。面试的时候有人问我:“你对多线程熟吗?”我差点回答:“熟?我每天都在跟它打仗。”
好了,正经点,Java里搞线程就像开了一间厨房,厨师(线程)多了,锅(共享资源)有限。你得学会调度,否则乱套。
线程生成,别一言不发
Java里线程生成有两种方式,我记得面试官喜欢考这一点:
- 继承Thread:直接让厨师自告奋勇干活。
class EggCooker extends Thread {
public void run() {
System.out.println("煎蛋ing...");
}
}
public class Demo {
public static void main(String[] args) {
Thread t = new EggCooker();
t.start();
}
}
- 实现Runnable接口:签合同,让人干活,但你可以随时换人。
class CoffeeMaker implements Runnable {
public void run() {
System.out.println("咖啡煮好了,闻到香味了吧!");
}
}
public class Demo2 {
public static void main(String[] args) {
Thread t = new Thread(new CoffeeMaker());
t.start();
}
}
面试常问:“为什么不直接继承Thread?”答案就是——Java只支持单继承,你继承了Thread就不能继承别的类了,所以Runnable更灵活。记住这个回答,我当时一说,面试官点头了。
线程状态,别光背词儿
线程状态面试官问得多,不仅是NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED,还爱问“状态切换为什么会发生?”
我当时比喻:
- NEW:刚入厨房,啥也没干
- RUNNABLE:已经在厨房忙活了,随时准备炒菜
- BLOCKED:锅被别人抢走,干瞪眼
- WAITING/TIMED_WAITING:站一边等调料或者倒水
- TERMINATED:活干完,回家睡觉
然后补一句:线程调度完全靠JVM和操作系统,你想让它顺序执行?呵呵,别做梦,除非你是面试官。
同步,锁,坑比比皆是
面试最爱问同步。为什么要同步?不用synchronized会怎样?我就说:“厨房锅没加锁,蛋和咖啡混一起,你吃了吗?”面试官笑,我也笑,但确实问题扎心。
示例:
class Counter {
private int count = 0;
public synchronized void inc() {
count++;
System.out.println(Thread.currentThread().getName() + " 计数:" + count);
}
}
public class Demo3 {
public static void main(String[] args) {
Counter c = new Counter();
for(int i=0; i<3; i++){
new Thread(() -> c.inc(), "Thread-"+i).start();
}
}
}
面试常问:“synchronized的锁粒度怎么选?”
我当时心里想——粒度大了,效率低,粒度小了,死锁可能来袭,面试官就喜欢你思考这个。
线程池,不用它你就是傻
再说线程池,面试喜欢问FixedPool和CachedPool的区别。我说:
- FixedPool:固定数量厨师,锅多了也等
- CachedPool:厨师不够?临时雇,活完就解雇
代码随便写个示例:
import java.util.concurrent.*;
public class KitchenDemo {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(2);
for(int i=0; i<5; i++){
int finalI = i;
pool.submit(() -> System.out.println("做菜-" + finalI + "完成"));
}
pool.shutdown();
}
}
面试官问:“线程池的拒绝策略你知道吗?”我说:“知道,就是告诉我厨房爆满,别再叫我了。”
volatile、CAS、原子类,小心面试陷阱
volatile?面试喜欢问:“能保证原子性吗?”你心里默念三遍:不,不,不。
CAS?乐观锁,面试官问你“ABA问题”,我当时想打个比方:有人换了锅,你没注意,又换回原来的锅,你还以为没动过——就ABA了。
面试真实感受
面试问线程的时候,别光背概念,要能说出感受。比如:“我做过一个日志处理系统,十几线程同时写,没加锁直接挂了,后来加了ReentrantLock,才稳得住。”
这类案例比任何官方词儿都能打动面试官。