# 52. 上下文切换优化分析

# 标准答案

✅ 减少上下文切换的优化策略:

  1. 线程优化

    • 合理设置线程数
    • 使用线程池
    • 避免线程饥饿
    • 控制任务粒度
  2. 锁优化

    • 减少锁粒度
    • 使用无锁数据结构
    • 避免锁竞争
    • 优化锁持有时间
  3. 算法优化

    • 批量处理
    • 异步处理
    • 任务分片
    • 数据本地化

# 答案解析

# 1️⃣ 线程池优化

public class OptimizedThreadPool {
    private final ThreadPoolExecutor executor;
    
    public OptimizedThreadPool() {
        int coreSize = Runtime.getRuntime().availableProcessors();
        executor = new ThreadPoolExecutor(
            coreSize,
            coreSize,
            0L, TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<>(1000),
            new ThreadPoolExecutor.CallerRunsPolicy()
        ) {
            @Override
            protected void beforeExecute(Thread t, Runnable r) {
                // 设置线程优先级
                Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
                // 设置线程亲和性
                setThreadAffinity(t);
            }
        };
        
        // 预热线程池
        warmUpThreadPool();
    }
    
    private void warmUpThreadPool() {
        for (int i = 0; i < executor.getCorePoolSize(); i++) {
            executor.submit(() -> {
                // 预热任务
                Thread.yield();
            });
        }
    }
    
    private void setThreadAffinity(Thread thread) {
        // 设置CPU亲和性,减少跨CPU调度
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 2️⃣ 批量处理优化

public class BatchProcessor {
    private static final int BATCH_SIZE = 1000;
    private final BlockingQueue<Task> taskQueue;
    private final ExecutorService executor;
    
    public void processTasks() {
        List<Task> batch = new ArrayList<>(BATCH_SIZE);
        
        while (true) {
            // 批量获取任务
            taskQueue.drainTo(batch, BATCH_SIZE);
            if (batch.isEmpty()) {
                break;
            }
            
            // 批量处理
            executor.submit(() -> {
                try {
                    processBatch(batch);
                } finally {
                    batch.clear();
                }
            });
        }
    }
    
    private void processBatch(List<Task> tasks) {
        // 分组处理
        Map<String, List<Task>> groups = tasks.stream()
            .collect(Collectors.groupingBy(Task::getType));
            
        // 并行处理各组任务
        groups.forEach((type, groupTasks) -> {
            // 一次性获取所需资源
            try (ResourceHolder resources = acquireResources(type)) {
                // 批量处理
                processTaskGroup(groupTasks, resources);
            }
        });
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 常见误区

  • 误区1:盲目增加线程数
  • 误区2:过度细粒度拆分

# 典型场景与解决方案

# ✅ 消息处理优化

public class MessageProcessor {
    private final int batchSize;
    private final DisruptorQueue<Message> queue;
    
    public void processMessages() {
        // 使用Disruptor避免锁竞争
        queue.consumeBatch(batchSize, messages -> {
            // 对消息进行分组
            Map<String, List<Message>> groups = 
                groupMessages(messages);
            
            // 并行处理各组消息
            groups.forEach((topic, topicMessages) -> {
                processMessageGroup(topicMessages);
            });
        });
    }
    
    private void processMessageGroup(List<Message> messages) {
        // 一次性申请资源
        try (MessageProcessor.Context ctx = createContext()) {
            // 批量处理
            for (Message msg : messages) {
                ctx.process(msg);
            }
            // 一次性提交
            ctx.commitAll();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 企业实战经验

# Situation(业务背景)

消息处理系统上下文切换频繁,性能下降。

# Task(核心任务)

优化系统减少上下文切换。

# Action(解决方案)

  1. 实现批量处理
  2. 优化线程模型
  3. 使用无锁队列
  4. 数据本地化处理

# Result(结果)

  • 上下文切换减少70%
  • 吞吐量提升200%
  • CPU利用率优化

# 深入追问

🔹 如何监控上下文切换?

  • 使用vmstat工具
  • 监控线程状态
  • 分析CPU使用率

🔹 如何选择合适的批处理大小?

  • 考虑延迟要求
  • 评估内存占用
  • 测试不同配置

# 相关面试题

  1. 上下文切换的成本是什么?
  2. 如何避免伪共享问题?
  3. CPU缓存对性能的影响?