Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在线程上下文中,String对象和StringBuffer对象之间有什么区别?_Java_Multithreading - Fatal编程技术网

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,因为两者都是可变的。我认为这个例子足够有效,因为引用在任何情况下都可能发生变化,导致读取,这可能不是用户期望的。另外,这个问题已经得到了很多关注,其中一个答案完全按照你的建议去做,所以没有必要再重复了。