A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 戚兴海 中级黑马   /  2014-2-24 17:08  /  1400 人查看  /  5 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

听老师说是单线程的时候StringBuilder效率高,多线程的时候StringBuffer高,能具体解释下么,还有没有其他方面的区别呢?

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

5 个回复

正序浏览
本帖最后由 薛旻 于 2014-2-25 13:02 编辑

你可以看一下源码,大致看看就有一个宏观了解了
AbstractStringBuilder
      |--StringBuffer
      |--StringBuilder
StringBulider和StringBuffer都继承了抽象类AbstractStringBuilder
有意思的是,抽象类AbstractStringBuilder基本实现了方法,因为是抽象类所以不能实例化
StringBuffer 在JDK1.0出现,它super了AbstractStringBuilder的方法,不过在函数上加了synchronized的同步关键字,让所有方法变成了同步方法,所以也就有了同步方法的优点和弊端,线程安全但是效率因此而降低
StringBuilder 在JDK1.5出现,它super了AbstractStringBuilder的方法,没有加synchronized关键字,所以也就线程不安全,但是效率也因此提升
所以,综上所述
如果单线程也就不涉及同步问题,所以可以选用高效率的StringBuilder
如果多线程也需要考虑同步问题的话,选择也比较多
可以使用已经实现同步的StringBuffer,也可以像源码一样将StringBuilder变成线程安全的,也可以使用新的线程锁Lock来同步StringBuilder来实现线程安全的目的。
回复 使用道具 举报
....... 来自手机 中级黑马 2014-2-25 11:55:44
报纸
很简单 一句话 StringBuilder是不同步的 另一个是同步的 如果你在用的时候 单线程用这个 多线程用另一个
回复 使用道具 举报
本帖最后由 梦里花-静 于 2014-2-25 09:50 编辑

String是长度不可变的,StringBuffer和StringBuilder长度都是可以变化的。
StringBuffer是线程安全的,StringBuilder不是线程安全的。
下面是例子:
package com.hct.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author: chengtai.he
* @created:2009-12-9 上午09:59:57
*/
public class StringBuilderTester {
private static final String base = " base string. ";
private static final int count = 2000000;
public static void stringTest() {
  long begin, end;
  begin = System.currentTimeMillis();
  String test = new String(base);
  for (int i = 0; i < count/100; i++) {
   test = test + " add ";
  }
  end = System.currentTimeMillis();
  System.out.println((end - begin)
    + " millis has elapsed when used String. ");
}
public static void stringBufferTest() {
  long begin, end;
  begin = System.currentTimeMillis();
  StringBuffer test = new StringBuffer(base);
  for (int i = 0; i < count; i++) {
   test = test.append(" add ");
  }
  end = System.currentTimeMillis();
  System.out.println((end - begin)
    + " millis has elapsed when used StringBuffer. ");
}
public static void stringBuilderTest() {
  long begin, end;
  begin = System.currentTimeMillis();
  StringBuilder test = new StringBuilder(base);
  for (int i = 0; i < count; i++) {
   test = test.append(" add ");
  }
  end = System.currentTimeMillis();
  System.out.println((end - begin)
    + " millis has elapsed when used StringBuilder. ");
}
public static String appendItemsToStringBuiler(List list) {
  StringBuilder b = new StringBuilder();
  for (Iterator i = list.iterator(); i.hasNext();) {
   b.append(i.next()).append(" ");
  }
  return b.toString();
}
public static void addToStringBuilder() {
  List list = new ArrayList();
  list.add(" I ");
  list.add(" play ");
  list.add(" Bourgeois ");
  list.add(" guitars ");
  list.add(" and ");
  list.add(" Huber ");
  list.add(" banjos ");
  System.out.println(StringBuilderTester.appendItemsToStirngBuffer(list));
}
public static String appendItemsToStirngBuffer(List list) {
  StringBuffer b = new StringBuffer();
  for (Iterator i = list.iterator(); i.hasNext();) {
   b.append(i.next()).append(" ");
  }
  return b.toString();
}
public static void addToStringBuffer() {
  List list = new ArrayList();
  list.add(" I ");
  list.add(" play ");
  list.add(" Bourgeois ");
  list.add(" guitars ");
  list.add(" and ");
  list.add(" Huber ");
  list.add(" banjos ");
  System.out.println(StringBuilderTester.appendItemsToStirngBuffer(list));
}
public static void main(String[] args) {
  stringTest();
  stringBufferTest();
  stringBuilderTest();
  addToStringBuffer();
  addToStringBuilder();
}
}

上面的程序结果如下: 5266 millis has elapsed when used String.
375 millis has elapsed when used StringBuffer.
281 millis has elapsed when used StringBuilder.
I   play   Bourgeois   guitars   and   Huber   banjos  
I   play   Bourgeois   guitars   and   Huber   banjos
从上面的结果来看,这三个类在单线程程序中的性能差别一目了然,采用String对象时,即使运行次数仅是采用其他对象的1/100,其执行时间仍然比其他对象高出25倍以上;而采用StringBuffer对象和采用StringBuilder对象的差别也比较明显,前者是后者的1.5倍左右。由此可见,如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;当然,如果要保证线程安全,自然非StringBuffer莫属了。

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

回复 使用道具 举报
4)StringBuffer和StringBuilder
1,字符串的组成原理就是通过该类实现的。
2,StringBuffer可以对字符串内容进行修改。
3,StringBuffer是一个容器。
4,很多方法与String形同。
5,StringBuffer是可变长度的。

JDK1.5版本之后出现了StringBuilder。

StringBuffer是线程同步。
StringBuilder是线程不同步。

以后开发,建议使用StringBuilder,提高效率。

升级三个因素:
1,提高效率
2,简化书写。
3,提高安全性。

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
StringBuilder 线程不同步 不安全 效率高
StringBuffer  线程同步   安全  效率低

单线程的话不存在同步   用StringBuilder
多线程的用StringBuffer   可以用StringBuilder + synchronized

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报 1 0
您需要登录后才可以回帖 登录 | 加入黑马