对于国内面试中经常问“StringBuffer和StringBuilder有何区别”,知乎上曾有一番讨论。
我以为,好的面试官可以在这个问题上直接进一步,“你不知道这两个的区别没关系,我可以告诉你,我们聊聊短生命周期对象管理和线程安全性吧。”所以取而代之的这样的一个问题就更有意义了:请写一个程序来验证StringBuffer和StringBuilder的线程安全性。
线程安全性是指,当对一个复杂对象进行某种操作时,从操作开始到操作结束之前,该对象会经历若干中间状态,直到操作完全结束,该对象才会会到完全可用的状态。如果其他线程能够访问处于不可用中间状态的对象,使该对象产生无法预料的结果,则称该对象线程不安全,反之则称其为线程安全。
所以这个简单程序的考察点:
- 线程安全性的理解
- Java并发编程基础
- 主动思考和分析能力,以及去求证的主动性,而不是被动接受各种结论
示例程序如下:
public class StringBufferAndStringBuilderTest { private static final int THREAD_NUM = 1000; public static void main(String[] args){ long startTime = System.currentTimeMillis(); String strToReverse = "AAAABBBB"; StringBuffer stringBuffer = new StringBuffer(strToReverse); StringBuilder stringBuilder = new StringBuilder(strToReverse); CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM); CountDownLatch countDownLatch2 = new CountDownLatch(THREAD_NUM); for(int i=0; i<THREAD_NUM; i++) { new StringBufferTaskThread(stringBuilder, countDownLatch).start(); new StringBufferTaskThread(stringBuffer, countDownLatch2).start(); } try { countDownLatch.await(); countDownLatch2.await(); System.out.println("StringBuffer toString: " + stringBuffer.toString()); System.out.println("StringBuilder toString: " + stringBuilder.toString()); long endTime = System.currentTimeMillis(); System.out.println("Running time: " + (endTime-startTime)); } catch (InterruptedException e) { e.printStackTrace(); } } } class StringBufferTaskThread extends Thread { private static final String STARTER = "-start"; private static final String ENDER = "-end"; private Object s = null; private CountDownLatch countDownLatch; // 记载运行线程数 public StringBufferTaskThread(StringBuilder stringBuilder, CountDownLatch countDownLatch) { super(); this.s = stringBuilder; this.countDownLatch = countDownLatch; } public StringBufferTaskThread(StringBuffer stringBuffer, CountDownLatch countDownLatch) { super(); this.s = stringBuffer; this.countDownLatch = countDownLatch; } @Override public void run() { System.out.println(Thread.currentThread().getName() + STARTER); for(int i=0; i<10; i++) { try { Thread.sleep(200); if(s instanceof StringBuffer){ ((StringBuffer) s).reverse(); System.out.println("Buffer->"+s.toString()); }else if(s instanceof StringBuilder){ ((StringBuilder) s).reverse(); System.out.println("Builder->"+s.toString()); } Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + ENDER); countDownLatch.countDown(); } }此示例程序做了如下事情:
- 基于初始字符串“AAAABBBB”分别构建StringBuffer和StringBuilder对象
- 分别启动1000个线程,调用StringBuffer和StringBuilder的reverse方法,进行字符串反转
- 所有线程执行完后打印结果,由于反转偶数次,线程安全的对象输出应与初始值相同,线程不安全的对象则可能产生乱序
输出:
Thread-0-start Thread-1-start Thread-2-start Thread-3-start Thread-4-start Thread-5-start Thread-6-start Thread-7-start .... Thread-368-end Thread-1809-end Thread-1609-end Thread-1810-end Thread-1608-end Thread-1702-end Thread-1527-end StringBuffer toString: AAAABBBB StringBuilder toString: ABBBBBAB Running time: 7523发现StringBuffer输出与初始值相同,StringBuilder输出产生乱序。多次执行或调大线程数StringBuffer输出结果不变,由此二者线程安全性得证。
相关推荐
String,StringBuffer,StringBuilder区别。几乎所有的应用开发都离不开操作字符串,理解字符串的设计和实现以及相关 工具如拼接类的使用,对写出高质量代码是非常有帮助的
String ,StringBuffer与StringBuilder的区别
String StringBuffer和StringBuilder 区别之源码解析 从源码角度简单对它们之间的区别进行了验证
StringBuffer:字符创变量 StringBuilder:字符创变量 从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:
介绍了String、StringBuffer、StringBuilder的使用方法,以及理论知识
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议...
简单的介绍了String、StringBuffer和StringBuilder的区别
StringBuffer和StringBuilder类的用法基本相同,但StringBuilder类的效率更高,因为它不是线程安全的; 二、StringBuffer的示例 // 创建一个空的StringBuffer对象 StringBuffer sb = new StringBuffer(); // 向...
String及StringBuffer和StringBuilder的区别
Java的StringBuffer和StringBuilder类是用于字符串操作的可变字符序列类。本文将介绍Java StringBuffer和StringBuilder类的常见操作和用法,包括创建、追加、插入、删除、替换、反转等操作。我们还会讨论如何获取...
string,stringbuffer,stringbuilder
Java中String,StringBuffer与StringBuilder的区别和用法。
目录StringStringBuffer与StringBuilder总结 String ...StringBuffer与StringBuilder 这两者基本相似,都是可变字符串对象,主要区别为线程是否安全。 总结 最后,引用菜鸟教程下的总结以及相关评论: S
String、StringBuilder和StringBuffer的区别 String、StringBuilder和StringBuffer的区别 String、StringBuilder和StringBuffer的区别
string,stringBuffer,stringBuilder
StringBuffer & StringBuilder 源码分析.docx
String、StringBuffer 和 StringBuilder 的区别 碎碎念 简单认识这三个对象 String StringBuffer StringBuilder 深入理解 String、StringBuilder、StringBuffer 从设计角度理解 String StringBuilder StringBuffer ...
java基础--4.常用类-3.StringBuffer、StringBuilder
Java中StringBuffer和StringBuilder_动力节点Java学院整理