2016-03-31 118 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功能所展示的。