• StringBuffer和StringBuilder


    StringBuffer和StringBuilder都是继承了抽象类AbstractStringBuilder

    为什么说StringBuilder不是线程安全的,而StringBuffer是线程安全的呢?

    我们去看看源码就知道了.

    先看

    StringBuilder的构造方法

        public StringBuilder append(String str) {
            super.append(str);
            return this;
        }

    这里的super的append方法就是AbstractStringBuilder抽象类的方法

        public AbstractStringBuilder append(String str) {
            if (str == null)
                return appendNull();
            int len = str.length();
            ensureCapacityInternal(count + len);
            str.getChars(0, len, value, count);
            count += len;
            return this;
        }

    1.这里的count是一个共享变量,对共享变量做+=操作是可能出现问题的,

    count += len;

    这不是一个原子操作,可能在多线程的时候出现问题.

    2.拷贝数据

        private void ensureCapacityInternal(int minimumCapacity) {
            // overflow-conscious code
            if (minimumCapacity - value.length > 0) {//如果要插入的字符和以前的已有的字符串的和大于现在的长度,那么就要执行copy了,把value拷贝的新的数组容器中
                value = Arrays.copyOf(value,
                        newCapacity(minimumCapacity));
            }
        }
        private int newCapacity(int minCapacity) {
            // overflow-conscious code
            int newCapacity = (value.length << 1) + 2;//扩容2的一次方倍+2,就是x*2+2
            if (newCapacity - minCapacity < 0) {//如果计算后的长度小于要扩容的长度,那就直接用着长度
                newCapacity = minCapacity;
            }
            return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)//如果newCapacity小于等于0,或者newCapacity比MAX_ARRAY_SIZE还大的话就返回字符实际的长度,否则返回计算后的长度newCapacity
                ? hugeCapacity(minCapacity)
                : newCapacity;
        }
        private int hugeCapacity(int minCapacity) {
            if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
                throw new OutOfMemoryError();
            }
            return (minCapacity > MAX_ARRAY_SIZE)
                ? minCapacity : MAX_ARRAY_SIZE;
        }
    是否比最大值大,如果大返回自己,否则返回最大值

    StringBuffer为什么是线程安全的,因为他有synchronized

        public synchronized StringBuffer append(String str) {
            toStringCache = null;
            super.append(str);
            return this;
        }

    所以他是线程安全的,但是效率比StringBuilder低一些

  • 相关阅读:
    Castle 1.0 RC2 尝鲜
    关注 Web Client Software Factory [Weekly Drop 08]
    ASP.NET AJAX入门系列
    Castle 1.0 Release Candidate 2发布
    ASP.NET AJAX入门系列(2):使用ScriptManager控件
    ASP.NET AJAX 1.0 Beta 发布相关文章总结及推荐
    关于ASP.NET AJAX的三个视频
    企业库2.0培训系列课程大纲[意见征询]
    Visual Studio“Orcas”October 2006 CTP版下载
    ASP.NET AJAX入门系列(4):使用UpdatePanel控件(一)
  • 原文地址:https://www.cnblogs.com/songfahzun/p/11573964.html
Copyright © 2020-2023  润新知