博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java.lang.StringBuffer源码分析
阅读量:5875 次
发布时间:2019-06-19

本文共 4950 字,大约阅读时间需要 16 分钟。

StringBuffer是一个线程安全的可变序列的字符数组对象,它与StringBuilder一样,继承父类AbstractStringBuilder。在多线程环境中,当方法操作是必须被同步,StringBuffer内的方法被同步化时,以实现跟在单线程中操作一样的一致性。

 

public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence {    //一个缓存用来存储最后一次调用toString返回的值,每当StringBuffer被修改就把该缓存清空    private transient char[] toStringCache;    public StringBuffer() {        super(16);    }    public StringBuffer(int capacity) {        super(capacity);    }    //...more constructs,提供与父类一致的构造器,StringBuffer的构造器总是调用父类的构造器        @Override    public synchronized int length() {
//返回容器中字符的数量 return count; } @Override public synchronized int capacity() {
//返回容器的大小 return value.length; } @Override public synchronized void ensureCapacity(int minimumCapacity) {
//保证容器足够大 if (minimumCapacity > value.length) { expandCapacity(minimumCapacity); } } @Override public synchronized void trimToSize() {
//将容器的大小与容器的字符数量变成一致的 super.trimToSize(); } //setLength是修改了StringBuffer,所以要把toStringCache设置为null public synchronized void setLength(int newLength) { toStringCache = null; super.setLength(newLength); } //...append,insert方法还有其他需要同步化的方法都是覆盖父类,用synchronized使方法同步化,同时那些修改了StringBuffer的方法,需要先把toStringCache设置为null //下面几个insert方法没有用synchronized来实现同步化,上面的解释说这些方法的同步化是通过调用其他StringBuffer方法来实现的 public StringBuffer insert(int dstOffset, CharSequence s) { // Note, synchronization achieved via invocations of other StringBuffer methods // after narrowing of s to specific type // Ditto for toStringCache clearing super.insert(dstOffset, s); return this; } public StringBuffer insert(int offset, boolean b) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of b to String by super class method // Ditto for toStringCache clearing super.insert(offset, b); return this; } public StringBuffer insert(int offset, int i) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of i to String by super class method // Ditto for toStringCache clearing super.insert(offset, i); return this; } public StringBuffer insert(int offset, long l) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of l to String by super class method // Ditto for toStringCache clearing super.insert(offset, l); return this; } public StringBuffer insert(int offset, float f) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of f to String by super class method // Ditto for toStringCache clearing super.insert(offset, f); return this; } public StringBuffer insert(int offset, double d) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of d to String by super class method // Ditto for toStringCache clearing super.insert(offset, d); return this; } public int indexOf(String str) { // Note, synchronization achieved via invocations of other StringBuffer methods return super.indexOf(str); } public int lastIndexOf(String str) { // Note, synchronization achieved via invocations of other StringBuffer methods return lastIndexOf(str, count); } //这个toString方法很重要,如果toStringCache为null时,会把当前的value复制一份新的给它,否则返回String(toStringCache) public synchronized String toString() { if (toStringCache == null) { toStringCache = Arrays.copyOfRange(value, 0, count); } return new String(toStringCache, true); } //下面的三个方法是为了实现StringBuffer的序列化和反序列化 private static final java.io.ObjectStreamField[] serialPersistentFields = { new java.io.ObjectStreamField("value", char[].class), new java.io.ObjectStreamField("count", Integer.TYPE), new java.io.ObjectStreamField("shared", Boolean.TYPE), }; private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { java.io.ObjectOutputStream.PutField fields = s.putFields(); fields.put("value", value); fields.put("count", count); fields.put("shared", false); s.writeFields(); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { java.io.ObjectInputStream.GetField fields = s.readFields(); value = (char[])fields.get("value", null); count = fields.get("count", 0); }

从上面源码可知,StringBuffer将父类非线程安全的方法都覆盖实现同步化,它自己拥有一个toStringCache的缓存,当这个缓存为空的时候,就知道StringBuffer被修改过了,这时候调用toString方法,就能得到被修改后最新的值。

转载于:https://www.cnblogs.com/13jhzeng/p/5624424.html

你可能感兴趣的文章
关于Linux系统使用遇到的问题-1:vi 打开只读(readonly)文件如何退出保存?
查看>>
pandas 按照某一列进行排序
查看>>
在WPF中如何使用RelativeSource绑定
查看>>
Map的深浅拷贝的探究
查看>>
XSLT语法 在.net中使用XSLT转换xml文档示例
查看>>
如何将lotus 通讯簿导入到outlook 2003中
查看>>
WinForm 应用程序中开启新的进程及控制
查看>>
前端工程师的职业发展路线在哪?
查看>>
IOS 内存警告 Memory warning level
查看>>
[转]PAC Manager: Ubuntu 上强大的 SSH 帐号管理工具,可取代 SecureCRT_Miracle_百度空间...
查看>>
顺序容器 (2)string类型操作
查看>>
转载:我最近的研究成果(IGeometry.Project and IGeometry.SpatialReference)
查看>>
提示框
查看>>
HDOJ1233 畅通工程之一(最小生成树-Kruscal)
查看>>
14Spring_AOP编程(AspectJ)_环绕通知
查看>>
PHP之打开文件
查看>>
iOS - OC SQLite 数据库存储
查看>>
PHP-mysqllib和mysqlnd
查看>>
Redis常用命令
查看>>
NeHe OpenGL教程 第三十五课:播放AVI
查看>>