CPU 调度算法
问题
操作系统的 CPU 调度算法有哪些?Java 线程调度是什么方式?
答案
常见调度算法
| 算法 | 原理 | 是否抢占 | 优缺点 |
|---|---|---|---|
| FCFS | 先来先服务 | 否 | 简单,但短任务可能等很久 |
| SJF | 最短作业优先 | 否 | 平均等待时间最短,但可能饿死长任务 |
| 优先级调度 | 按优先级执行 | 是/否 | 灵活,但低优先级可能饿死 |
| 时间片轮转(RR) | 每个进程分配时间片 | 是 | 公平,响应快 |
| 多级反馈队列 | 多个优先级队列 + 动态调整 | 是 | 兼顾交互和批处理 |
多级反馈队列(Linux 主流)
高优先级 [Q1: 时间片 10ms] → 用完降级
↓
中优先级 [Q2: 时间片 20ms] → 用完降级
↓
低优先级 [Q3: 时间片 40ms] → FCFS
- 新进程先进入最高优先级队列
- 时间片用完没执行完,降到下一级
- IO 密集型任务经常主动让出 CPU,会停留在高优先级
Java 线程调度
Java 线程的调度完全由操作系统决定。Thread.setPriority() 只是"建议",不保证效果。
Thread t = new Thread(() -> { /* ... */ });
t.setPriority(Thread.MAX_PRIORITY); // 10,仅建议
t.start();
常见面试问题
Q1: 时间片设多长合适?
答案:
- 太短:频繁上下文切换,CPU 时间浪费在切换上
- 太长:进程响应慢,退化为 FCFS
- Linux 通常在 1ms - 10ms 之间,CFS 调度器根据进程数动态调整
Q2: 什么是线程饥饿?
答案:
低优先级线程长时间得不到 CPU 执行机会。解决方案:
- 老化(Aging):等待时间越长,优先级越高
- Java 中使用公平锁(
new ReentrantLock(true))保证等待最久的线程先获得锁