2016-03-31 119 views
0

我看过代码,大多数时候人们已经使用过StringBuffer,只是为了避免多线程的问题,但是我不能来到需要StringBuffer的一般情况(大部分时间) 。在多线程环境中使用StringBuilder

如果我有像下面的方法 - private String getPath(){ return new StringBuilder("a").append("b").toString(); }

即使这种方法会被多个线程使用它应该没问题。 (?) 因为我们正在创建一个新的Stringbuilder,并且每个线程都有自己的栈(引用)副本。

仅当我们将StringBuilder作为方法参数时才会出现问题。

+0

你是什么意思?“即使这个方法将被多个线程使用,它应该没问题。”?多线程(如果没有实现锁定)的主要问题是共享数据的一致性。如果您在几个线程之间共享一个字符串,并且其中一些可以写入它,则每个线程可能会读取不同的字符串值。如果每次从函数中创建一个新的(常量值)字符串,则不存在这样的问题,但是无论如何您都可以返回一个常量字符串值。所以我假设你打算返回一些变量的值,对吗? –

+0

以上例(示例),这里每个线程将调用getPath()方法,它每次实例化一个新的StringBuilder并返回一个字符串(它是不可变的)。那么,在这种情况下,我需要使用StringBuffer吗? – Ouney

+0

我相信你不需要 –

回答

0

你的假设是对的。每个调用getPath的线程将创建一个新的StringBuilder,当然不同的线程可以并行处理不同的StringBuilder对象。所以你不需要在这里使用StringBuffer

StringBuilder作为参数传递给getPath时,您会遇到问题。但StringBuffer不会在这种情况下,因为不同的线程会追加到相同的StringBuffergetPath可能会返回像“aab”混合物。在使用传递的StringBuffer时,您需要在getPath方法的开始和结尾处进行全局锁定。

0

如果StringBuilder是您班级的成员,这对您可能很重要。

因此,您可以在某些任务结束前将其输出到缓冲区,然后将其输出到缓冲区中,然后才能将其用于收集文本。

class Gatherer { 

    StringBuffer buffer = new StringBuffer(); 

    public void gatherEvent(Object o) { 

     buffer.append(o); 
    } 

    public String toString() { 

     return buffer.toString(); 
    } 

    public void reset() { 

     buffer.setLength(0); 
    } 
} 

你宁愿用StringBuffer在多线程环境使得gather并发调用会不会破坏彼此。当然,还有更好的方法可以做到这一点,比如存储在Object[]和懒惰评估toString()

您可以在每次重置缓冲区时添加优化,而不是创建新实例,这正是上面的reset功能所展示的。