StringBuffer追加 - jvm中发生了什么

时间:2011-03-18 13:55:46

标签: java

我有一个while循环来使用字符串缓冲区进行字符串追加。在jvm中发生了什么,因为append方法是同步的,每次都在对象上检查锁,并在调用append时继续。

6 个答案:

答案 0 :(得分:4)

别介意,只需使用StringBuilder代替:

  

可变的字符序列。这个   class提供了兼容的API   StringBuffer,但不保证   同步。 这门课是   设计用作插入式   在地方替换StringBuffer   使用字符串缓冲区的地方   通过单个线程(通常如此)   案子)。 在可能的情况下,它是   建议使用此类   首选的是StringBuffer   在大多数实施中都要快。

但要回答你的问题,请阅读: Java Tutorial > Synchronized Methods

答案 1 :(得分:3)

是的,单线程代码(或线程之间不共享StringBuffer的多线程代码)不需要同步StringBuffer

这就是StringBuilder引入的原因,它具有相同的 API,但具有非同步方法。

但请注意,那些synchronized个关键字的性能损失应该绝对最小,因为无争议的锁在Java中非常非常快。

答案 2 :(得分:2)

如果您没有编写多线程代码,则没有理由使用StringBuffer。请改用StringBuilder。它的API是相同的,但StringBuilder不是线程安全的。

  

此类设计用作单个线程使用字符串缓冲区的地方StringBuffer的替代品(通常情况下)。在可能的情况下,建议优先使用此类StringBuffer,因为在大多数实现中它会更快。

     

StringBuilder的实例不适合多线程使用。如果需要此类同步,则建议使用StringBuffer

答案 3 :(得分:1)

在某种理论意义上,锁定是为每次操作获取和释放的。实际上,对于频繁使用的代码路径,执行锁定粗化优化。因此,连续的几个操作共享相同的锁获取和释放。

另请注意,它往往是使用锁的同一个线程(它是每个实例的锁)。典型的JVM实现会偏向锁定以便从特定线程使用,从而使整个过程非常快。正如其他人所提到的,几乎没有必要使用StringBuffer多线程(对于其他微同步也是如此),所以你不妨使用StringBuilder

答案 4 :(得分:0)

是的,使用synchronized方法的一般规则适用于此处。另外,如果您使用的是单线程方案,请考虑使用StringBuilder,如果不能,请至少尝试使用StringBuffer的Threadlocal版本。

答案 5 :(得分:0)

即使通过StringBuffer进行同步,也很难在多个线程中合理使用。即如果你在这样的两个主题中附加文本片段。

thread A: stringBuffer.append("key1").append("= ").append("value1").append("\n");
thread B: stringBuffer.append("key2").append("= ").append("value2").append("\n");

即使它是线程安全的,你仍然可以获得

key1key2= = value2\nvalue1\n

以及许多其他组合。