为什么要使用StringBuilder? StringBuffer可以同时使用多个线程吗?

| 假设我们的应用程序只有一个线程。并且我们正在使用
StringBuffer
,这是什么问题? 我的意思是如果“ 0”可以通过同步处理多个线程,那么使用单线程有什么问题? 为什么改用
StringBuilder
?     
已邀请:
        “ 3”是线程安全的,这意味着它们具有同步方法来控制访问,因此一次只有一个线程可以访问StringBuffer对象的同步代码。因此,在多个线程可能试图同时访问同一StringBuffer对象的多线程环境中,StringBuffer对象通常是安全的。
StringBuilder\'s
访问未同步,因此不是线程安全的。通过不同步,StringBuilder的性能可以比StringBuffer更好。因此,如果您在单线程环境中工作,则使用StringBuilder代替StringBuffer可能会提高性能。在其他情况下也是如此,例如StringBuilder局部变量(即方法中的变量),其中只有一个线程将访问StringBuilder对象。 因此,更喜欢
StringBuilder
,因为, 性能增益小。 StringBuilder是StringBuffer类的1:1替代品。 StringBuilder不是线程同步的,因此在大多数Java实现上表现更好 看一下这个 : 不要使用StringBuffer! StringBuffer与StringBuilder的性能比较     
        StringBuilder应该是(微小的)更快的速度,因为它不同步(线程安全)。 您会注意到真正繁重的应用程序之间的差异。   通常应优先使用StringBuilder类,因为它支持所有相同的操作,但是它更快,因为它不执行任何同步,因此它优先于该类。 http://download.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html     
        在多个线程中使用StringBuffer几乎是无用的,实际上几乎永远不会发生。 考虑以下
Thread1: sb.append(key1).append(\"=\").append(value1);
Thread2: sb.append(key2).append(\"=\").append(value2);
每个追加都是同步的,但是线程可以在任何时候弯腰,因此您可以具有以下任意组合以及更多
key1=value1key2=value2
key1key2==value2value1
key2key1=value1=value2
key2=key1=value2value1
可以通过一次同步整行来避免这种情况,但是这使使用StringBuffer而不是StringBuilder失去了意义。 即使您具有正确同步的视图,它也比仅创建整个行的线程本地副本要复杂得多,例如一次将StringBuilder和日志行发送到类似Writer的类。     
        在单线程应用程序中,“ 0”是正确的。它会和ѭ2work一样工作。 唯一的区别是通过拥有所有同步方法而增加的微小开销,这在单线程应用程序中没有任何优势。 我认为引入introduced2ѭ的主要原因是,编译器在编译包含
String
并置的代码时使用
StringBuffer
(现在是
StringBuilder
):在那种情况下,同步永远是没有必要的,并且可以用不同步的
StringBuilder
替换所有这些位置。提供小的性能改进。     
        
StringBuilder
具有更好的性能,因为它的方法不同步。 因此,如果您不需要同时构建一个String(无论如何这都是非常不典型的情况),那么就不需要为不必要的同步开销“付出”。     
        这对你们有帮助 是Straight Builder比Buffer更快,
public class ConcatPerf {
        private static final int ITERATIONS = 100000;
        private static final int BUFFSIZE = 16;

        private void concatStrAdd() {
            System.out.print(\"concatStrAdd   -> \");
            long startTime = System.currentTimeMillis();
            String concat = new String(\"\");
            for (int i = 0; i < ITERATIONS; i++) {
                concat += i % 10;
            }
            //System.out.println(\"Content: \" + concat);
            long endTime = System.currentTimeMillis();
            System.out.print(\"length: \" + concat.length());
            System.out.println(\" time: \" + (endTime - startTime));
        }

        private void concatStrBuff() {
            System.out.print(\"concatStrBuff  -> \");
            long startTime = System.currentTimeMillis();
            StringBuffer concat = new StringBuffer(BUFFSIZE);
            for (int i = 0; i < ITERATIONS; i++) {
                concat.append(i % 10);
            }
            long endTime = System.currentTimeMillis();
            //System.out.println(\"Content: \" + concat);
            System.out.print(\"length: \" + concat.length());
            System.out.println(\" time: \" + (endTime - startTime));
        }

        private void concatStrBuild() {
            System.out.print(\"concatStrBuild -> \");
            long startTime = System.currentTimeMillis();
            StringBuilder concat = new StringBuilder(BUFFSIZE);
            for (int i = 0; i < ITERATIONS; i++) {
                concat.append(i % 10);
            }
            long endTime = System.currentTimeMillis();
           // System.out.println(\"Content: \" + concat);
            System.out.print(\"length: \" + concat.length());
            System.out.println(\" time: \" + (endTime - startTime));
        }

        public static void main(String[] args) {
            ConcatPerf st = new ConcatPerf();
            System.out.println(\"Iterations: \" + ITERATIONS);
            System.out.println(\"Buffer    : \" + BUFFSIZE);

            st.concatStrBuff();
            st.concatStrBuild();
            st.concatStrAdd();
        }
    }

Output  

    run:
    Iterations: 100000
    Buffer    : 16
    concatStrBuff  -> length: 100000 time: 11
    concatStrBuild -> length: 100000 time: 4
    concatStrAdd   -> 
    
        Manish,尽管在您的StringBuffer实例上只有一个线程在运行,但是每当调用它的任何方法时,获取和释放StringBuffer实例上的监视器锁都会有一些开销。因此,StringBuilder是单线程环境中的首选。     
同步对象要付出巨大的代价。不要将程序视为独立实体;当您阅读这些概念并将其应用于问题详细信息中提到的小型程序时,这并不是问题,当我们要扩展系统时,就会出现问题。在这种情况下,您的单线程程序可能依赖于其他几种方法/程序/实体,因此就性能而言,同步对象可能会导致严重的编程复杂性。因此,如果您确定不需要同步对象,则应使用StringBuilder,因为它是一种良好的编程习惯。最后,我们想学习编程以制作可扩展的高性能系统,这就是我们应该做的!     

要回复问题请先登录注册