假设我们的应用程序只有一个线程。而我们正在使用StringBuffer
那么问题是什么?为什么要使用StringBuilder? StringBuffer可以使用多个线程以及一个线程?
我的意思是,如果StringBuffer
可通过同步处理多个线程,什么是单线程工作的问题?
为什么使用StringBuilder
呢?
假设我们的应用程序只有一个线程。而我们正在使用StringBuffer
那么问题是什么?为什么要使用StringBuilder? StringBuffer可以使用多个线程以及一个线程?
我的意思是,如果StringBuffer
可通过同步处理多个线程,什么是单线程工作的问题?
为什么使用StringBuilder
呢?
StringBuffers
是线程安全的,这意味着他们已经同步方法来控制访问,以便只有一个线程可以同时访问一个StringBuffer对象的同步代码。因此,在多线程环境中,StringBuffer对象通常是安全的,因为多线程可能试图同时访问同一个StringBuffer对象。
StringBuilder's
访问不是同步的,这样它不是线程安全的。通过不同步,StringBuilder的性能可以优于StringBuffer。因此,如果您正在单线程环境中工作,则使用StringBuilder而不是StringBuffer可能会提高性能。对于其他情况也是如此,例如只有一个线程访问StringBuilder对象的StringBuilder局部变量(即方法内的变量)。
所以,喜欢StringBuilder
因为,
检查了这一点:
StringBuilder的应该是一个(微小)快一点,因为它是不同步的(线程安全)。
您可以注意到真正沉重的应用程序中的差异。
由于StringBuilder类支持所有相同的操作,但它的速度更快,因为它不执行同步,所以通常应该优先使用StringBuilder类。
http://download.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html
请再次阅读此问题... – 2011-05-30 09:20:01
@MANISH PATHAK - 请阅读答案 - 问题:为什么要使用StringBuilder? - 答案:StringBuilder应该是一个(微小的)位更快一点(第一句 – 2011-05-30 09:49:50
澄清:即使一个线程正在使用对象,synchronized方法也会强制线程获取并释放每个访问的监视器。这可能会减慢程序。 – Jonathan 2011-05-30 10:53:39
StringBuilder
具有更好的性能,因为它的方法是不同步的。
所以,如果你不需要同时建立一个字符串(这是一个相当非典型scenarion反正),那么就没有必要“支付”了不必要的同步开销。
你可以描述这种情况吗? – 2011-05-30 09:22:51
@Manish - 不,我不能,因为实际上我无法想象一个场景,我不得不选择StringBuffer而不是StringBuilder。 – 2011-05-30 10:56:49
谢谢安德烈亚斯... 我从上面的帖子了解它。 感谢所有 – 2011-05-30 12:57:36
StringBuffer
不错在单线程应用程序中。它的工作方式和StringBuilder
一样。
唯一的区别是通过具有所有同步方法添加的微小开销,这在单线程应用程序中没有任何优势。
我的看法是,主要原因StringBuilder
引入的是,编译器使用StringBuffer
(现在StringBuilder
),当它编译包含String
级联码:在这种情况下同步从未必要的和更换所有的具有非同步StringBuilder
的地方可以提供较小的性能改进。
在多个线程中使用StringBuffer几乎没用,实际上几乎从不发生。
考虑以下
Thread1: sb.append(key1).append("=").append(value1);
Thread2: sb.append(key2).append("=").append(value2);
每条附加是同步的,但一个线程可以在任何时候弯腰弯那么你可以有以下任一组合,更
key1=value1key2=value2
key1key2==value2value1
key2key1=value1=value2
key2=key1=value2value1
这可以通过以下方法避免在同一时间同步整条线,但是这违背了使用StringBuffer而不是StringBuilder的要点。
即使您拥有正确同步的视图,它也不仅仅是创建整行的线程本地副本, StringBuilder和一次登录到像Writer这样的类。
这将帮助u人, 是直Builder是不是缓冲速度更快,
public class ConcatPerf {
private static final int ITERATIONS = 100000;
private static final int BUFFSIZE = 16;
private void concatStrAdd() {
System.out.print("concatStrAdd -> ");
long startTime = System.currentTimeMillis();
String concat = new String("");
for (int i = 0; i < ITERATIONS; i++) {
concat += i % 10;
}
//System.out.println("Content: " + concat);
long endTime = System.currentTimeMillis();
System.out.print("length: " + concat.length());
System.out.println(" time: " + (endTime - startTime));
}
private void concatStrBuff() {
System.out.print("concatStrBuff -> ");
long startTime = System.currentTimeMillis();
StringBuffer concat = new StringBuffer(BUFFSIZE);
for (int i = 0; i < ITERATIONS; i++) {
concat.append(i % 10);
}
long endTime = System.currentTimeMillis();
//System.out.println("Content: " + concat);
System.out.print("length: " + concat.length());
System.out.println(" time: " + (endTime - startTime));
}
private void concatStrBuild() {
System.out.print("concatStrBuild -> ");
long startTime = System.currentTimeMillis();
StringBuilder concat = new StringBuilder(BUFFSIZE);
for (int i = 0; i < ITERATIONS; i++) {
concat.append(i % 10);
}
long endTime = System.currentTimeMillis();
// System.out.println("Content: " + concat);
System.out.print("length: " + concat.length());
System.out.println(" time: " + (endTime - startTime));
}
public static void main(String[] args) {
ConcatPerf st = new ConcatPerf();
System.out.println("Iterations: " + ITERATIONS);
System.out.println("Buffer : " + BUFFSIZE);
st.concatStrBuff();
st.concatStrBuild();
st.concatStrAdd();
}
}
Output
run:
Iterations: 100000
Buffer : 16
concatStrBuff -> length: 100000 time: 11
concatStrBuild -> length: 100000 time: 4
concatStrAdd ->
马尼什,虽然只有一个线程在您的StringBuffer实例运行着,在获取和释放监视器一些开销无论何时调用其任何方法,都会锁定StringBuffer实例。因此StringBuilder是单线程环境中的首选。
同步对象的成本很高。没有将程序看作是独立的实体;当你阅读概念并将它们应用于你的问题细节中提到的小程序时,它不是问题,当我们想要扩展系统时会出现问题。在这种情况下,您的单线程程序可能依赖于其他几个方法/程序/实体,因此同步对象在性能方面会导致严重的编程复杂性。所以如果你确定没有必要同步一个对象,那么你应该使用StringBuilder,因为这是一个很好的编程习惯。最后,我们想要学习编程来制作可扩展的高性能系统,所以这就是我们应该做的!
最好说StringBuffer是“线程安全的”,但它很容易调整两个线程竞争相同的缓冲区导致竞争条件。即使您需要在线程之间共享字符串缓冲区,您很可能需要对其执行更高级别的控制,而不是它所显示的同步方法。因此,除非第三方库要求您使用StringBuffer,否则不能考虑使用StringBuffer的很多理由,或者为了传统/小众目的。 – locka 2014-03-28 10:48:06
'StringBuilder'并不完全是'StringBuffer'的1:1替代品。例如,Matcher的appendReplacement方法需要一个StringBuffer作为它的第一个参数。 – 2018-01-09 21:19:42