为什么我的StringBuffer未同步,StringBuilder却表现出同步特性?
问题原因分析
- 第一点:你当前的测试逻辑存在先天的时序问题:两个线程启动后均调用了
Thread.sleep(3000),会在几乎同一时间唤醒执行后续逻辑,两者的执行顺序完全由操作系统随机调度,不存在谁先谁后的固定顺序,输出本身就存在随机性。 - 第二点:你错误理解了StringBuffer的线程安全范围:StringBuffer的线程安全仅保障自身单个方法(如
append()、toString())的原子性,不会出现多线程调用单个方法时的数据错乱。但你代码中if(strBuf.toString().equals("")) { strBuf.append("xxx") }是两个独立操作的复合逻辑,这个组合操作整体没有加锁,不具备原子性。
两个线程可以同时完成「判断为空」的步骤,之后先后执行append操作,最终StringBuffer的结果就会是两个字符串拼接的结果,和你预期的只有一个值不符。 - 第三点:你看到的StringBuilder反而只有一个值的情况,完全是线程调度的偶然结果:刚好某一个线程完整执行完「判断为空+append」的全部逻辑后,另一个线程才开始判断,此时StringBuilder已经不为空,所以第二个线程不会执行append。这种结果不固定,多运行几次你会看到两种对象的输出都存在多种可能。
- 补充测试建议:如果要正确验证两者的线程安全差异,应该测试多线程并发执行大量append操作的场景:StringBuffer不会出现字符错乱、长度不符合预期、抛出数组越界异常的问题,而StringBuilder则可能出现上述异常。
内容的提问来源于stack exchange,提问作者mAsK
相关产品推荐
相关产品推荐

