String,StringBuilder和StringBuffer。

速度

速度
String字符串常量
StringBuffer字符串变量(线程安全)
StringBuilder字符串变量(非线程安全)
简单的说,String类型与StringBuffer类型及StringBuilder类型最大差别在于String是不可变的对象,也就是说,每次对String类型进行改变的时候其实都等于生成了一个新的String对象,然后将指针指向新的String对象,例如

String  str="abc";
System.out.println(str);
str=str+"de";
System.out.println(str);
StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
System.out.println(stringBuilder.toString());

如果运行这几行代码会发现输出结果分别为"abc",“abcde"和"abcde”。对于第一次输出的"abcde"(也就是第二个str),好像是str由原来的abc改为了abcde。其实,过程却并不是这样,JVM对这几行的代码处理实际是这样,首先创建一个str对象,将值"abc"赋值给str,然后在第三行,JVM又创建了一个新的String对象也命名为str,然后把原来的str和"de"加起来赋值给新的str对象,而后指针指向新的str,而原始的str和"de"这个两块内存并不会及时被gc,gc是在JVM的某个时候才开始操作,所以会由于新开辟内存,并且回收内存,引起速度变慢。所以str实际上并没有改变,也就是说,String对象一旦创建之后就不可更改了。所以java对String修改的操作就是不断创建新对象回收旧对象的一个过程。而StringBuilder和StringBuffer的对象都是变量,对变量进行操作就是直接对该对象进行修改,而不是重新创建回收,所以速度要快的多。`

String str="abc"+"de";
String str1="abc";
String str2="de";
String str3=str1+str2;

第一行代码,许多人会认为和第四行代码一样,其实不然。这行代码执行的时候,首先会将"abc"和"de"加起来然后再复制给str,也就是说系统并没有重新创建和回收新的对象。就算这两个相加的字符串无限长,也是String效率最高,因为在编译的时候已经组装好了。而第四行str1+str2就算都是"1",在编译的时候也并不会帮你组装,所以创建时等于额外创建了StringBuilder来完成str1+str2的操作。
线程
线程
在多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全。A线程修改了B线程处理的数据,而B线程又修改了A线程处理的数据,显然这是由于全局资源造成的,为了解决此问题,优先考虑使用局部变量,退而求其次使用同步代码块,这样就不得不牺牲系统处理性能,加在多线程并发时资源挣夺最激烈的地方,这就实现了线程的同步机制
同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求
不到,怎么办,A线程只能等待下去
异步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为没有同步机制存在,A线程
仍然请求的到,A线程无需等待
显然,同步最最安全,最保险的。而异步不安全,容易导致死锁,这样一个线程死掉就会导致整个
进程崩溃,但没有同步机制的存在,性能会有所提升。在Java中,提供了两种方式来实现同步互斥访问:synchronized和Lock。
synchronized
在Java中,可以使用synchronized关键字来标记一个方法或者代码块,当某个线程调用该对象的synchronized方法或者访问synchronized代码块时,这个线程便获得了该对象的锁,其他线程暂时无法访问这个方法,只有等待这个方法执行完毕或者代码块执行完毕,这个线程才会释放该对象的锁,其他线程才能执行这个方法或者代码块。

String中的对象是不可变的,也就可以理解为常量,显然线程安全。AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。如果对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder
StringBuilder拓展
虽然 StringBuilder对象是动态对象,允许扩充它所封装的字符串中字符的数量,但是您可以为它可容纳的最大字符数指定一个值。此值称为该对象的容量,不应将它与当前 StringBuilder对象容纳的字符串长度混淆在一起。当修改 StringBuilder时,在达到容量之前,它不会为其自己重新分配空间。当达到容量时,将自动分配新的空间且容量翻倍。
常用方法
(1)Append 方法可用来将文本或对象的字符串表示形式添加到由当前 StringBuilder对象表示的字符串的结尾处。

StringBuilder  MyStringBuilder=new StringBuilder("hello");
	MyStringBuilder.Append("World");

输出为"helloWorld"。
(2)Insert 方法将字符串或对象添加到当前 StringBuilder中的指定位置。

StringBuilder  MyStringBuilder=new StringBuilder("hello");
MyStringBuilder.Insert(2,"World");

输出为"heWorldllo"。
(3)可以使用 Remove方法从当前 StringBuilder中移除指定数量的字符,移除过程从指定的从零开始的索引处开始。

StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Remove(5,7);

输出"Hello"
总结
当我们不太需要字符串的大量修改时,使用String,当我们需要对字符串进行大量修改时,我们可以使用StringBuilder(操作字符串的效率最高,比StringBuffer还高百分之十左右),当多线程时,使用StringBuffer。以上便是我对这三个类型的总结,我作为一个正在学java的新手,可能会有许多地方不足甚至错误。