14

複数の部分から文字列を作成していて、どちらStringBufferかを使用したい、または使用したいStringBuilder。Java 5 docs から、可能な場合はそれが推奨されることがわかりますが、次StringBuilderの点に注意してください。

のインスタンスはStringBuilder、複数のスレッドで安全に使用できません。

StringBuilderこのステートメントから、単一のインスタンスを複数のスレッドで共有するべきではないことがわかります。しかし、次の場合はどうでしょうか。

//Is this safe?
//foo() is called simultaneously by multiple threads
String foo(String a, String b) {
    return new StringBuilder(a).append(b).toString();
}

ここでは、StringBuilderクラスを同時に使用して関数内に同時に複数のスレッドが存在する可能性がありますが (たとえば、静的変数が存在する場合は、その変数への同時アクセスなど)、各スレッドは独自のStringBuilder. ドキュメントから、これが複数のスレッドによる使用としてカウントされるかどうかを判断することはできません。

4

5 に答える 5

19

それはまったく問題ありません。ローカル変数は、インスタンスまたはクラス変数にアクセスしたり変更したりしない限り、スレッド セーフに問題はありません。

于 2009-03-10T18:28:23.767 に答える
11

はい、安全です。StringBuilder オブジェクトはローカルでのみ使用されるためです (foo() を呼び出す各スレッドは、独自の StringBuilder を生成します)。

また、投稿したコードは、これによって生成されたバイトコードと実質的に同じであることに注意してください。

String foo(String a, String b) {
    return a + b;
}
于 2009-03-10T18:29:05.857 に答える
6

あなたが持っているコードは安全です。

このコードはそうではありません。

public class Foo
{
    // safe
    private final static StringBuilder builder;

    public static void foo()
    {
        // safe
        builder = new StringBuilder();
    }

    public static void foo(final String a)
    {
        // unsafe
        builder.append(a);
    }

    public synchronized void bar(final String a)
    {
        // safe
        builder.append(a);
    }
}

ローカルデータのみを使用するローカル変数には、スレッドセーフの問題はありません。クラスまたはインスタンスのメソッド/変数レベルで表示されるデータの処理を開始すると、スレッドセーフの問題が発生する可能性があります。

于 2009-03-11T02:38:55.273 に答える
4

他の回答に同意します-メモだけです。

StringBuffer が複数のスレッドで使用されている場合は、おそらく完全に壊れたユース ケースです。これは、単一の文字列が準ランダムな順序で構築されていることを意味するため、StringBuffer スレッドを作成しても意味がありません。安全。

于 2009-03-10T18:32:49.950 に答える
3

Java は StringBuilder を自動的に選択するため、このコードが必要かどうかはわかりません。パフォーマンスに問題がない場合は、a + b を使用してください。

パフォーマンスが必要な場合は、次のことを試してください。

return new StringBuilder(
a.length() + b.length()).append(a).append(b).toString();

バッファーのサイズを正しく設定し、VM がバッファーのサイズを変更して途中で収集するガベージを作成しないようにします。

于 2009-03-10T18:38:01.467 に答える