Java 在线程上下文中,String对象和StringBuffer对象之间有什么区别?
字符串对象是不可变的,因此它本质上是线程安全的,所以我可以在线程上下文中使用它而无需同步Java 在线程上下文中,String对象和StringBuffer对象之间有什么区别?,java,multithreading,Java,Multithreading,字符串对象是不可变的,因此它本质上是线程安全的,所以我可以在线程上下文中使用它而无需同步 StringBuffer对象的方法是同步的,因此如果线程试图执行其方法,则如果不同步,则不会出现问题 但在线程上下文中将其对象用作资源需要进行同步。 我无法清楚地理解突出显示的部分。请任何人解释或提供代码参考,以消除我的疑问。如果你看一下,它说明了以下内容: 每当发生涉及源序列的操作(例如从源序列追加或插入)时,此类仅在执行该操作的字符串缓冲区上同步,而不是在源上同步 这意味着,如果多个线程可以访问源代码,
StringBuffer
对象的方法是同步的,因此如果线程试图执行其方法,则如果不同步,则不会出现问题
但在线程上下文中将其对象用作资源需要进行同步。
我无法清楚地理解突出显示的部分。请任何人解释或提供代码参考,以消除我的疑问。如果你看一下,它说明了以下内容:
每当发生涉及源序列的操作(例如从源序列追加或插入)时,此类仅在执行该操作的字符串缓冲区上同步,而不是在源上同步
这意味着,如果多个线程可以访问源代码,则可能是另一个线程在写入源代码之前修改了源代码
一个简单的例子,这可能会使这一点更清楚
StrginBuffer sb = new StringBuffer
//some other thread might change the sharedSource.
sb.append(getSharedString());
从:
每当发生涉及源序列的操作(例如从源序列追加或插入)时,此类仅在执行该操作的字符串缓冲区上同步,而不是在源上同步
这意味着,例如,如果您有如下代码:
StringBuffer bufferOne = new StringBuffer("abc");
StringBuffer bufferTwo = new StringBuffer("def");
bufferOne.append(bufferTwo);
然后它仅在bufferOne
上同步,而不是在bufferTwo
上同步。换句话说,在执行此操作时,其他一些线程可能会读取或写入bufferTwo
。字符串是不可变的(一旦创建就不能更改)对象。创建为字符串的对象存储在常量字符串池中。
Java中的每个不可变对象都是线程安全的,这意味着字符串也是线程安全的。字符串不能由两个线程同时使用。
字符串一旦分配就不能更改
String demo = " hello " ;
demo1=new StringBuffer("Bye");
//上述对象存储在常量字符串池中,不能修改其值
demo="Bye" ;
//新的“Bye”字符串在常量池中创建,并由演示变量引用//“hello”字符串仍存在于字符串常量池中,其值未被重写,但我们丢失了对“hello”字符串的引用 StringBuffer是可变的,这意味着可以更改对象的值。通过StringBuffer创建的对象存储在堆中。StringBuffer具有与StringBuilder相同的方法,但StringBuffer中的每个方法都是同步的,即StringBuffer是线程安全的
StringBuilder demo2= new StringBuilder("Hello");
因此,它不允许两个线程同时访问同一个方法。每个方法一次只能由一个线程访问
但是线程安全也有缺点,因为StringBuffer的性能受线程安全属性的影响。因此,当调用每个类的相同方法时,StringBuilder比StringBuffer更快
StringBuffer value can be changed , it means it can be assigned to the new value
可以使用toString()方法将字符串缓冲区转换为字符串
//上面的对象存储在heap中,并且可以更改其值
String demo = " hello " ;
demo1=new StringBuffer("Bye");
//上面的语句是正确的,因为它修改了StringBuffer中允许的值
StringBuilder is same as the StringBuffer , that is it stores the object in heap and it can also be modified . The main difference between the StringBuffer and StringBuilder is that StringBuilder is also not thread safe.
StringBuilder速度很快,因为它不是线程安全的
StringBuilder demo2= new StringBuilder("Hello");
//上述对象也存储在堆中,可以修改其值
demo2=new StringBuilder("Bye");
事实并非如此。您仍然需要同步它的调用。粗体句子的来源或上下文是什么?您需要给出您正在阅读的内容的参考。另请参阅本文:请注意,在实际代码中,您几乎应该始终使用
StringBuilder
;事实上,StringBuffer
的现代实现只是一个围绕它的同步包装器。因为您没有将sharedSource定义为final,所以您可以将它分配给其他值。sharedSource的内容无法更改。字符串是不可变的。单独线程上的任何活动都不会产生任何影响。哦,糟糕的例子,我已经更新了。谢谢@BrettOkken!也许更好的例子是使用CharSequence或另一个StringBuffer,因为两者都是可变的。我认为这个例子足够有效,因为引用在任何情况下都可能发生变化,导致读取,这可能不是用户期望的。另外,这个问题已经得到了很多关注,其中一个答案完全按照你的建议去做,所以没有必要再重复了。