为什么StringBuffer有一个toStringCache而StringBuilder没有? [英] Why StringBuffer has a toStringCache while StringBuilder not?

查看:443
本文介绍了为什么StringBuffer有一个toStringCache而StringBuilder没有?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JDK 8中, StringBuffer 类有一个 toStringCache ,而 StringBuilder 没有。

In JDK 8, StringBuffer class has a toStringCache, while StringBuilder doesn't.

/**
 * A cache of the last value returned by toString. Cleared
 * whenever the StringBuffer is modified.
 */
private transient char[] toStringCache;

但为什么?


  • 我能想到的一个可能原因是StringBuffer已经同步,因此可以更容易地实现缓存。

  • One possible reason I can think of is that StringBuffer is already synchronized so a cache can be implemented easier.

或者历史上可能是StringBuffer是这样实现的,所以旧代码在很大程度上依赖于这个特性?

Or maybe historically StringBuffer was implemented this way so old code depends heavily on this feature?

鉴于现代JVM具有转义分析和偏向锁定,差异是否相关?

Given modern JVM with escape analysis and biased locking, is the difference relevant anymore?

推荐答案

考虑历史背景可能会有所帮助。 Java $ 5引入了 StringBuilder ,因为它已被识别, StringBuffer 不适合其实际使用case。

It might help to consider the historical context. StringBuilder was introduced with Java 5, since it has been recognized, that StringBuffer isn’t well suited for its actual use cases.

新推出的 StringBuilder 专为构建,使用和立即删除的主要用例而设计之后,在纯粹的本地环境中。因此,它不提供任何同步,并且它不会打扰优化其多次调用其 toString()方法的罕见情况而没有中间更改(当这真的发生在现实生活中吗?),特别是在提供缓存功能而不牺牲无线程同步的性能优势的情况下,介于硬到不可能之间。

The newly introduced StringBuilder has been designed for the major use case of being constructed, used and immediately dropped afterwards, in a purely local context. Therefore, it doesn’t provide any synchronization and it doesn’t bother optimizing the rare case of its toString() method being called multiple times without an in-between change (when does this happen in real life at all?), especially as, indeed, providing the caching feature without sacrificing the performance advantage of no thread synchronization, is somewhere between "hard" to "impossible".

虽然 StringBuilder 被记录为不是线程安全的,所以你知道在同时调用它上面的方法时会发生不一致的事情,类 String 通过不变性保证是线程安全的,因此,不能允许 StringBuilder 缺少同步可能导致已经不一致构造字符串,而不是在 String StringBuilder 之间共享数组,是最安全的解决方案。

While StringBuilder is documented to be not thread safe, so you know inconsistent things could happen when calling methods on it concurrently, the class String is guaranteed to be thread safe through immutability, hence, it must not be allowed that StringBuilder’s absence of synchronization can causes inconsistencies in already constructed strings and, not sharing the array between String and StringBuilder at all, is the safest solution.

那么为什么要优化呢?如果它在现实生活中几乎没有任何好处?好吧,因为它存在很长一段时间,很可能甚至自Java 1.0以来,它不值得更改类 StringBuffer 中的任何内容。它的存在可能没有任何真正的优势,但也没有删除它,这将需要新的测试等等,可能会变成空格键过热功能 ...

So why is this optimization there, if it hardly ever has a benefit in real life? Well, because it’s there since a very long time, most likely even since Java 1.0 and it’s not worth changing anything in the class StringBuffer. Its presence may not have any real advantage, but neither has removing it, which would require new testing and so on and could turn out to be the space bar overheating feature for some application…

您可能会注意到,在Java 1.x中,做出了很多设计决策今天看起来很奇怪。在基础类中过度使用 synchronized 就是其中之一,这几乎无法帮助优化另一个。当时,即使是不可变性的含义也没有得到很好的理解,这就是为什么我们有多余的方法,比如 String.valueOf(char []) String.copyValueOf(char []) ,还有机会使用 new String(char []) ...

You may notice that back-then, in Java 1.x, a lot of design decision were made that may look strange today. Overusing synchronized in fundamental classes is one of them, this hardly ever helping optimization another one. At that time, even the implications of immutability were not well understood, which is why we have redundant methods like String.valueOf(char[]) and String.copyValueOf(char[]), plus the opportunity to use new String(char[])

这篇关于为什么StringBuffer有一个toStringCache而StringBuilder没有?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆