StringBuild的高性能场景下的使用

StringBuilder与StringBuffer

一个线程不安全一个线程安全.但StringBuilder效率更高.

如何高性能场景下使用StringBuilder

首先,我们得了解StringBuilder存在的两个问题,线程不安全以及char[]重复扩容的影响.
new StringBuilder() 时char[]的默认长度是16,然后,如果要append第17个字符,怎么办?用System.arraycopy成倍复制扩容!这样一来有数组拷贝的成本,二来原来的char[]也白白浪费了要被GC掉。可以想见,一个129字符长度的字符串,经过了16,32,64, 128四次的复制和丢弃,合共申请了496字符的数组,在高性能场景下,这几乎不能忍。

如何解决(参考jdk的BigDecimal类)

BigDecimal里面有这么两段代码
1.通过ThreadLocal封装StringBuilderHelper

private static final ThreadLocal
        threadLocalStringBuilderHelper = new ThreadLocal() {
        @Override
        protected StringBuilderHelper initialValue() {
            return new StringBuilderHelper();
        }
    };

2.StringBuilderHelper的主要定义

static class StringBuilderHelper {
        final StringBuilder sb;    // Placeholder for BigDecimal string
        final char[] cmpCharArray; // character array to place the intCompact

        StringBuilderHelper() {
            sb = new StringBuilder();
            // All non negative longs can be made to fit into 19 character array.
            cmpCharArray = new char[19];
        }

        // Accessors.
        StringBuilder getStringBuilder() {
            sb.setLength(0);
            return sb;
        }
    }

ThreadLocal的使用解决了StringBuilder的并发不安全问题.
StringBuilder.setLength()函数重置它的count指针,而char[]则会继续重用,而toString()时会把当前的count指针也作为参数传给String的构造函数,所以不用担心把超过新内容大小的旧内容也传进去了。
cmpCharArray = new char[19]指定大小,包含最大long值.

你可能感兴趣的:(StringBuild的高性能场景下的使用)