zoukankan      html  css  js  c++  java
  • java.lang.StringBuffer源码分析

    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方法,就能得到被修改后最新的值。

  • 相关阅读:
    关于callback
    vue项目前端限制页面长时间未操作超时退出到登录页
    vue 项目文件流数据格式转blob图片预览展示
    You are using the runtime-only build of Vue where the template compiler is not available.
    element-ui el-cascader级联选择器设置指定层级不能选中
    vue项目中图片预览旋转功能
    nhandled rejection Error: EPERM: operation not permitted, open 'C:Program Files odejs ode_cache npm ERR! cb() never called!
    vue+element-ui upload图片上传前大小超过4m,自动压缩到指定大小,长宽
    vue+element-ui 项目中实现复制文字链接功能
    vue项目js实现图片放大镜功能
  • 原文地址:https://www.cnblogs.com/13jhzeng/p/5624424.html
Copyright © 2011-2022 走看看