Java Lock机制疑问:为何最终count值为0?
问题原因解析
1. 主线程未等待子线程完成,提前读取初始值
启动t1、t2、t3三个子线程后,主线程不会自动等待这些子线程执行完毕,会立刻往下执行System.out.println语句。这时候子线程可能还没开始执行count++的逻辑,所以主线程读取到的是Shared.count的初始值0。
2. 控制台打印顺序的误导
你看到子线程的所有打印都在主线程输出之前,是因为System.out.println是线程安全的(内部用synchronized做了同步),子线程的循环打印会连续占用输出流的锁,而主线程的输出语句虽然先执行,但受限于输出流的缓冲和锁竞争,导致它的输出被延迟显示,给你造成了“子线程先执行完”的错觉。
3. 内存可见性的隐性问题
Shared.count是静态变量,但没有加volatile修饰,也没有通过同步机制(比如Lock的lock/unlock)确保主线程能看到子线程的修改。就算子线程在主线程输出前已经改了count,主线程也可能因为工作内存的缓存,读到的还是旧值0。
为什么加join()就正常了?
Thread.join()的作用是让主线程等待对应子线程彻底执行完再继续:
- 确保三个子线程的5次
count++全部执行完毕,累加出15; join()会触发happens-before规则,保证子线程对count的所有修改都能被主线程看到,所以最终能输出正确的结果。
内容的提问来源于stack exchange,提问作者Sanchit Jain
相关产品推荐
相关产品推荐

