1、String:在字符串不经常变化的场景中可以使用String类,如:常量的声明、少量的变量运算等。
2、StringBuffer:在频繁进行字符串的运算(拼接、替换、删除等),并且运行在多线程的环境中,则可以考虑使用StringBuffer,例如XML解析、HTTP参数解析和封装等。
3、StringBuilder:在频繁进行字符串的运算(拼接、替换、删除等),并且运行在多线程的环境中,则可以考虑使用StringBuffer,如SQL语句的拼装、JSON封装等
demo
入口类
package com.other;
import org.junit.Test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 多个线程操作同一个StringBuilder ,导致打印结果异常,验证出StringBuilder为非线性安全
*/
public class Client {
@Test
public void test(){
ExecutorService executorService = Executors.newFixedThreadPool(2);//新建线程池,有两个线程
for(int i=0;i<100;i++) {//启用100个线程执行
executorService.execute(new MyThread());
}
}
}
打印结果:
696996696996
696996696996
699696699996
699696699996
699696699996结论:非预期的666666999999或999999666666,所以证明StringBuilder非线性安全。
验证类
package com.other;
/**
* 测试非线性安全
*/
public class MyThread implements Runnable {
//非线性安全
static StringBuilder stringBuilder = new StringBuilder("666666999999");//静态变量,线程共享
//线性安全
// static StringBuffer stringBuilder = new StringBuffer("666666999999");//静态变量,线程共享
@Override
public void run() {
for(int i=0;i<100;i++){
stringBuilder.reverse();
}
System.out.println(stringBuilder);
}
}