zoukankan      html  css  js  c++  java
  • 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低一些

  • 相关阅读:
    判断点是否在一个任意多边形中
    linux 内存布局以及tlb更新的一些理解
    java(内部类)
    java(面向对象 )
    java(数组及常用简单算法 )
    java(运算符,控制流程语句,函数 )
    deep-in-es6(七)
    Java(标识符,关键字,注释,常量,变量)
    MarkDown study:
    *LeetCode--Ransom Note
  • 原文地址:https://www.cnblogs.com/songfahzun/p/11573964.html
Copyright © 2011-2022 走看看