1. 问题背景与核心挑战
在并发编程中,按序打印问题是一个经典的多线程同步案例。假设我们有三个线程A、B、C,需要严格按照A→B→C的顺序打印输出,每个线程打印若干次。这个看似简单的需求背后,隐藏着线程同步的核心难题——如何确保线程执行的顺序性。
我曾在分布式日志系统中遇到过类似场景,不同服务产生的日志需要按时间顺序合并,但各服务时钟可能存在微小偏差。通过原子操作实现的顺序控制,最终解决了日志乱序问题。下面分享这个案例的技术实现方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 原子操作与同步原语选型
2.1 为什么需要原子操作
当多个线程共享状态变量时,传统的if(flag==1)判断存在风险:在判断与执行之间可能发生线程切换。我曾用以下代码模拟这个风险:
java复制// 错误示例
if (state == 1) {
// 此处可能被其他线程抢占
print("A");
state = 2;
}
通过添加Thread.sleep(1)人为制造线程切换,可以稳定复现顺序错乱。这证明了非原子操作的不可靠性。
2.2 主流同步方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| synchronized | 简单可靠 | 性能开销较大 | 通用场景 |
| ReentrantLock | 可中断、可定时 | 需手动释放锁 | 复杂同步需求 |
| AtomicInteger | 无锁、高性能 | 只适合简单状态 | 计数器等简单状态 |
| Semaphore | 灵活控制并发数 | 实现顺序控制较复杂 | 资源池管理 |
在按序打印场景中,AtomicInteger的CAS操作是最佳选择。实测对比显示,相
