Java多线程counter值异常咨询:为何有时<10000?能否超20000?
问题解答
你的解释是否正确?
完全正确,这正是counter有时小于10000的核心原因。本质是**counter++并非原子操作**,它会被拆成三个独立步骤:读取当前counter的值、对读取到的值加1、将新值写回内存。当线程被操作系统调度器中途打断时,就会出现"旧值覆盖新值"的丢失更新问题。
就像你描述的场景:t1线程读取counter=567后被暂停,主线程趁机把counter加到了5699;等t1恢复执行时,它依然拿着之前读取的旧值567做加1操作,然后把568写回内存,直接覆盖了主线程算出的5699。后续t1继续自增到3056,等于主线程的5000多次自增操作全被无效覆盖,最终结果自然会远低于预期的10000。
程序能否输出大于20000的数值?
不可能。两个线程各自最多执行10000次自增操作,哪怕没有任何线程安全问题,最终结果的上限就是20000。线程调度只会导致操作被覆盖、计数不增加,不可能让总操作次数凭空变多。
举个极端例子:两个线程同时读取counter=0,各自加1得到1后写回,最终counter还是1——这相当于两次操作只生效了一次,结果比20000少;但无论怎么调度,两个线程的自增操作总次数加起来最多就是20000次,不可能额外多算,所以结果绝对不会超过20000。
内容的提问来源于stack exchange,提问作者Spektra Lami
相关产品推荐
相关产品推荐

