2016-03-31 34 views
0

複数のスレッドに関する問題を避けるために、ほとんどの場合StringBufferを使用したコードがありますが、StringBufferが必要な一般的なケース(ほとんどの場合)では対応できません。 。私はこの方法以下のようにしている場合マルチスレッド環境でのStringBuilderの使用

- このメソッドは、複数のスレッドによって使用されるにもかかわらずprivate String getPath(){ return new StringBuilder("a").append("b").toString(); }

それは大丈夫でなければなりません。 (?) 新しいStringbuilderを作成しているため、すべてのスレッドはスタック(参照)に独自のコピーを持ちます。

メソッドの引数としてStringBuilderを取得している場合のみ問題になります。

+0

「このメソッドは複数のスレッドで使用されますが、大丈夫です」とはどういう意味ですか?マルチスレッドの主な問題(ロックが実装されていない場合)は、共有データの一貫性です。文字列を複数のスレッド間で共有し、それらのうちのいくつかがスレッドに書き込むことができる場合、各スレッドは異なる文字列値を読み取ることがあります。毎回関数から新しい(定数値)文字列を作成する場合、そのような問題はありませんが、とにかくconst文字列値を返すこともできます。だから私はあなたが正しい変数の値を返そうとしていると思いますか? –

+0

上記の例では、各スレッドはgetPath()メソッドを呼び出し、毎回新しいStringBuilderをインスタンス化し、文字列を返します(これは不変です)。だから、私はこの場合StringBufferを使用する必要がありますか? – Ouney

+0

私はあなたが信じていないと信じています –

答えて

0

あなたの前提は正しいです。 getPathを呼び出す各スレッドは、新しいStringBuilderを作成します。もちろん、別のスレッドは異なるStringBuilderオブジェクトを同時に処理することができます。だからここでStringBufferを使う必要はありません。

StringBuilderをパラメータとしてgetPathに渡すと問題が発生します。しかし、StringBufferは、異なるスレッドが同じStringBufferに追加され、getPathが "aab"のような混合を返す可能性があるため、このケースでは役に立たないでしょう。 getPathメソッドの開始時と終了時に、グローバルにロックする必要がありますが、渡されたStringBufferを使用しています。

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); 
    } 
} 

あなたはgatherの同時呼び出しが互いを壊しないようにマルチスレッド環境でのStringBufferを使用することを好むだろう。もちろん、Object[]の配列に格納し、遅い評価をtoString()に格納するなど、これを行うためのより良い方法があります。

上記のreset関数が示すとおり、バッファをリセットするだけで新しいインスタンスを作成するのではなく、最適化を追加することもできます。

関連する問題