1、运行速度的差别:
StringBuilder(非线程安全) > StringBuffer(线程安全) > String(线程安全)
原因:
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
而StringBuilder和StringBuffer一个有考虑线程安全一个没有。
public class Test {
static final int N=50000;
@SuppressWarnings({ "unused", "null" })
public static void main(String[] args) {
long starTime = System.currentTimeMillis();
String str = "";
for (int i = 0; i < N; i++) {
str += i;
}
long endTime = System.currentTimeMillis();
System.out.println("String +=用时:"+(endTime - starTime)+"毫秒");
long starTime1 = System.currentTimeMillis();
StringBuffer str1 = new StringBuffer();
for (int i = 0; i < N; i++) {
str1.append(i);
}
long endTime1 = System.currentTimeMillis();
System.out.println("StringBuffer的append用时:"+(endTime1 - starTime1)+"毫秒");
long starTime2 = System.currentTimeMillis();
StringBuilder str2 = new StringBuilder();
for (int i = 0; i < N; i++) {
str2.append(i);
}
long endTime2 = System.currentTimeMillis();
System.out.println("StringBuffer的append用时:"+(endTime2 - starTime2)+"毫秒");
}
}
生成结果:
String +=用时:3427毫秒
StringBuffer的append用时:6毫秒
StringBuffer的append用时:2毫秒
StringBuffer 与 StringBuilder线程安全问题对比:
public class Test {
public static void main(String[] args) {
testStringBuilderAndStringBuffer();
}
public static void testStringBuilderAndStringBuffer(){
//证明StringBuffer线程安全,StringBuilder线程不安全
StringBuffer stringBuffer = new StringBuffer();
StringBuilder stringBuilder = new StringBuilder();
CountDownLatch latch1 = new CountDownLatch(1000);
CountDownLatch latch2 = new CountDownLatch(1000);
for(int i=0;i<1000;i++){
new Thread(new Runnable() {
@Override
public void run() {
try {
stringBuilder.append(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
latch1.countDown();
}
}
}).start();
}
for(int i=0;i<1000;i++){
new Thread(new Runnable() {
@Override
public void run() {
try {
stringBuffer.append(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
latch2.countDown();
}
}
}).start();
}
try {
latch1.await();
System.out.println(stringBuilder.length());
latch2.await();
System.out.println(stringBuffer.length());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出结果:
999
1000
990
1000
996
1000