我有一个while循环来使用字符串缓冲区进行字符串追加。在jvm中发生了什么,因为append方法是同步的,每次都在对象上检查锁,并在调用append时继续。
答案 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
以及许多其他组合。