为什么不要用 StringBuffer 和 Vector
来源:互联网 发布:凯立德端口查看 编辑:程序博客网 时间:2024/04/29 01:46
把贴吧一大神(那十无忧)的文章总结到此:
http://tieba.baidu.com/p/1443344962#0-qzone-1-78428-d020d2d2a4e8d1a374a433f596ad1440
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
很多人在回答新手提问的时候会说,StringBuilder 是非同步的,所以快一些,StringBuffer是同步(线程An全)的,所以慢一些。从技术上说这句话是没有错的,但是为什么又不要用 StringBuffer 呢?
简单的说,StringBuffer的“线程An全”在大多数时候增加了大量不必要的成本,并且未必达到目的。
看下面的代码:
StringBuffer buffer = getStringBuffer();
for(int i=0; i<10000; i++)
buffer.append(i);
StringBuffer 的每一步操作都先获取同步锁,然后释放同步锁。
所以这段代码中,它获取了10000次锁,释放了10000次锁。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
除了获取、释放10000次锁的高昂成本之外,它真的实现了“线程AN全”的目的吗?
假如在这个for循环运行的过程中,有另一个线程对 buffer 做了操作:
buffer.append("some string");
那么这个 "some string" 就会**入某两个数字之间!因为在任意两次 append 数字之间,有一个“释放锁”再“获取锁”的极短暂的间隔,这时候是可以被其他线程获取锁的。
换句话说,StringBuffer 所提供的所谓“线程AN全”,并不包括多个操作之间的“原子性”支持。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
要想前述的for循环不受干扰地完成,用户还是需要手动上锁:
final StringBuffer buffer = getStringBuffer();
synchronized(buffer) {
for(int i=0; i<10000; i++)
buffer.append(i);
}
这样是保证了在for循环运行期间不受其他线程干扰,可是如前所述,10000次锁值 +1 和 -1 的成本还是有的,并且这个成本变成了“完全没有必要”的无意义成本。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
这就是为什么 StringBuffer 这个类天生缺陷。
在API设计中有一条规则是这样说的:
一个类不应该自己实现同步,而应该把同步的工作留给用户。
这句话也是本帖的目的所在: 在绝大多数情况下,把同步的工作留给应用代码,而不是工具类的代码。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
各位看官可以拜访原帖,浏览评论交流内容~
这位大神如果不高兴.......................................不高兴你来喷我啊!
- 为什么不要用 StringBuffer 和 Vector
- 善用StringBuffer和Vector
- StringBuffer和Vector的高效率使用
- 为什么不要用eval函数
- Vector与ArrayList,Stringbuffer和StringBuilder和String
- vector 循环中不要用erase
- 为什么不要重载 && 和 || 操作符!!!
- 为什么不要重载&&和||操作符
- ★为什么不要和“穷人”做朋友?
- 为什么vector需要和synchronized同时使用
- Vector 和 ArrayList 哪一个更好? 为什么?
- 不要使用vector<bool>
- 为什么一般用vector<string> 而非 vector<char*>
- 从为什么String=String谈到StringBuilder和StringBuffer
- 从为什么String=String谈到StringBuilder和StringBuffer
- 从为什么 String=String 谈到 StringBuilder 和 StringBuffer
- 从为什么String=String谈到StringBuilder和StringBuffer
- 为什么Service层最好不要和Dao层参数同名
- hdu 2865 Birthday Toy (polya,好题)
- MySQL高效分页解决方案集
- 黑马程序员 IO心得总结
- iOS中消息的传递机制
- oracle数据库中,数据表无法执行数据操作语句,提示记录已被锁住
- 为什么不要用 StringBuffer 和 Vector
- 状态机的实现
- java 的运行机制之classload
- Regex expressions in Java \\s vs.\\s+
- glutSwapBuffers函数用法
- 开始
- onNewIntent
- string和stringstream用法总结
- 黑马程序员——java-网络编程