StringBuilderまたはStringBufferはいつ使用する必要がありますか?


13

実稼働Webアプリケーションでは、私の仲間のプログラマーがStringBufferをどこでも使用していました。現在、アプリケーションの開発と修正を担当しています。StringBuilderStringBufferを読んだ後、すべてのStringBufferコードをStringBuilderに置き換えることにしました。これは、データBeanでスレッドセーフが必要ないためです。

例:(各データBeanでStringBufferの使用を確認できます)

@Override
public String toString() {
    StringBuffer sb = new StringBuffer();// replace it from StringBuilder
    sb.append(" ABCD : ").append(abcd);
    sb.append(", EFGH : ").append(efgh);
    sb.append(", IJKL : ").append(ijkl);
}

セッション/リクエストごとに個別のデータBeanを作成します。セッションは、他のユーザーがアクセスできない単一のユーザーによって使用されます。

移行する前に他の点を考慮する必要がありますか?

単一のスレッドがある場合(待機中のスレッドがないか、新しいスレッドがオブジェクトロックを探していない場合)、StringBufferまたはStringBuilderのどちらでも同様に実行されます。StringBufferの場合、オブジェクトロックを取得するのに時間がかかることは知っていますが、オブジェクトロックの保持/解放を除いて、それらの間にパフォーマンスの違いがあるかどうかを知りたいです。


9
sb例のようにローカル変数として使用する場合、スレッドセーフはまったく問題になりません。たとえ1,000個のスレッドが同時にメソッドに入ったとしても、各スレッドは独自のローカル変数を持つ独自の呼び出しスタックを持ちます。StringBuildersが互いに干渉することはありません。
fredoverflow

私はいつも、誰がaのインターフェースのようなものに沿って2つのスレッドを同期したいのだろうと思っていましたStringBuffer。そのようなコードを見たことはありませんが、マルチスレッドの観点から見ると、これは悪い設計だとほぼ確信しています。StringBufferインターフェースに沿ってスレッドを同期するのは悪い考えだと思うので、このクラスは存在するべきではなく、常に使用するべきだと思いますStringBuilder。すでに述べたように、StringBuffer歴史的な理由で存在しています。
pasztorpisti

回答:


22

2つの唯一の違いは、StringBufferで使用される同期です。同期のオーバーヘッドは、物事の大規模なスキームではそれほど大きなものではありませんが、それらを持たないStringBuilderメソッドと比較すると重要です。JVMは、特に1つのスレッドのみなどで、他の方法では必要のない作業を実行しています。

コードが機能し、人々がパフォーマンスについて文句を言っていなければ、私はそれについて心配しません。あなたはあなたの金のために多くの強打を得るつもりはありません。ただし、新しいコードを記述している場合、またはStringBufferを使用するコードを更新している場合は、StringBuilderを同時に変換することをお勧めします。


これに加えて、2つのスレッドの安全性を継承することに留意する必要があります。StringBuilderはスレッドセーフではありません。
マルタインVerburg

2
それはで指摘されたaltough @MartijnVerburg真、stackoverflow.com/questions/6775016/stringbuffer-is-obsolete/...文字列ビルダーの同じインスタンスを使用する複数のスレッドを必要とする非常に少数のユースケースがあること。
マシューフリン

4
@MartijnVerburg:また、注意する必要があります。本当にスレッドセーフ必要な場合は、それでも十分ではない可能性があります。ブレーキをかけないことを保証しますが、複数のスレッドが一度にアクセスする場合、追加する位置を簡単に制御できないため、別の外部同期が必要になります。StringBuffer
ヨアヒムザウアー

8

StringBuilderは、より適切で高速なStringBufferになるように(Java 1.5)ポイントに追加され、コンパイラはそれを内部で使用して、+文字列に演算子を実装します。

つまり、StringBuilderを使用すると、クラスが導入されたときよりも古いJVMでコードを実行することはできません。しばらくの間、これは私たちにとって問題になるでしょう。常に最新のものを実行する場合は、気にする必要はありません。

以下の理由からですが、あなたが経験する最適化プロセスは経験しません。

  • タイトなループの外側では、利点は無視できます。プロファイラーで明示的にホットスポットとして表示されない限り、気にしません。
  • コードを変更するとエラーが発生する可能性があるため、アプリケーションを徹底的に再テストする必要があります。それは、非同期の設定で同期されたクラスで生活するよりもはるかに高価かもしれません。

私はあなたに同意します..まだあなたのOutside tight loops the advantage is negligible...
主張

StringBufferとは対照的に、StringBuilderに欠けているメカニズムは、スレッドセキュリティと速度のトレードオフです。それが行われている場合にのみ問題になるように速度向上は、非常に小さく、多くの、これは通常何回も行われている小さなループの場合である-時間のを。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.