********************************************我所知道的,
StringBuffer是单线程的,效率低,安全用于多线程的程序当中
StringBuilder是多线程的,效率高,不安全,用于单线程中,提高安全性
但是在开发中具体应该用在哪里?这个很让我困惑.希望能帮我解答一下.谢谢各位了.
********************************************
1. 首先说一下 为什么要用String的容器类:
比如 我们在程序中很容易出现下面的代码- int sum =0;
- for(int i=0; i<100; i++){
- sum+= i;
- }
复制代码 这里面sum必须一直累加才能保证是求和运算的结果
运算的过程你应该很清楚吧 就是 在栈内存中开辟一个空间 叫sum 一直修改sum中的值
好 现在需求变一下: 我想通过循环产生一个新的字符串“abcdefghi...z”
这个时候 最原始的作法就是仿照上面累加求和的例子做成下面的样子:- String s="";
- for(char ch ='a'; ch <='z'; ch++){
- s = s+ch;
- }
- System.out.println(s);
复制代码 这样会达到目的。但是 注意“abc”这样的事字符串常量对象 常量的意思就是不能被改变 所以字符串常量对象就是一旦被初始化 就不能再改变的
并且这些字符串常量对象全部存储在方法区的常量池里面 这样 你看
初始化 String s=""的时候 ""存储在常量池里面
第一次循环"a" 第二次循环"ab" 第三次循环“abc” 一直到最后一次循环“abcde...z”产生了这么多常量对象都需要内存空间来存储 全部存储在常量池里面
所以 你想一下 要是你的程序很复杂 设计很多字符串操作 都按照基本数据类型的累加来操作 会浪费很多的内存的空间的
2. 这样 人们就想:能不能也像对基本数据类型的修改一样,也是在原来的内存空间修改字符串的值而不新开辟内存空间呢?
这样就出现了StringBuffer这个类 这个类的实例 你就可以像String类的实例s一样操作你的想法:
把有s的地方换成- StringBuffer sf= new StringBuffer();
- for(char ch ='a'; ch <='z'; ch++){
- sf.append(ch+"");
- }
- System.out.println(sf.toString());
复制代码 这样 每次修改的中间变量都会在堆内存(引用sf指向的内存空间)中进行修改。这样就不会产生很多中间变量存储在常量池了。
3.StringBuilder和StringBuffer
《1》StringBuffer先出现的。是设计成线程同步的。多线程数据访问这个容器时,由于是线程同步,每一个线程都要读这个容器的锁判断是不是被占用。是就要等待。
这个对锁的判断也是要耗费时间的 即使是没有被占用的情况 线程依旧要判断所得情况
为了提高线程访问StringBuffer容器的效率 Java工程师们在后面的Java版本中设计出来新的功能和StringBuffer一样的类 只不过没有线程同步这一说
这样线程访问这个StringBuilder容器的时候,就不用判断锁的使用情况了,极大地提高了效率。
《2》毕老师这个时候说了:那要是也是多线程访问还想用StringBuilder该怎么办? 老师说:自己在StringBuilder所在的代码块加锁即可
|