2

StringBuilderとStringBufferの使用についてこのStackoverflowスレッドを読んでいました。

結論としては、StringBufferが同期され、スレッドセーフであり、それらではないStringBuilderと比較してパフォーマンスが少し劣ることを除いて、2つのコレクションは同じものであるように見えました。

誰かが、ArrayListとVectorの間に同様の関係がどのように存在するかを提起しました。

複数のスレッドを意識的に作成していない限り、同期されたコレクション(または他のもの)を使用しないことは良い(安全な)経験則ですか?

つまり、「可能な限り新しいStringBuilderを使用してください。」というメッセージが表示されました。知りたいのは、それが可能であることをどのように確認できるかということです。

意図的に新しいスレッドを作成しない限り、同期されていないコレクションを使用しても安全ですか?

4

7 に答える 7

5

同期が必要であることが確実になるまで、同期されていないものを使用します。

StringBufferたとえば、問題の一部はVector、それらが常に正しい方法で同期されているとは限らないことです。の場合、すべての操作を個別に同期させる必要があるVectorとは限りません。多くの場合、実際に必要なのは、操作のブロックを同期することです...これは必ずしもまたはよりも優れているとは限りません。VectorArrayListCollections.synchronizedList

同時実行性と複数のスレッドを使用していることがわかっている場合は、必要な同期の詳細を検討しますが、交換StringBufferするStringBuilderだけでは、誤った安心感が得られるだけです。後で同時実行性を使用することにした場合でも、そうではありません。必然的に正しい種類の並行性。

(現在スレッドを使用していない場合は、検索して置き換えることは絶対に問題ありません。推奨されますStringBufferStringBuilder上記の引数は逆方向です。)

于 2012-08-09T16:18:11.777 に答える
1

この質問に自分で答える方法がわかるまでは、常にノンブロッキングを使用してください。すべてを同期するのは本当に簡単で、スレッドの作成と開始もとても簡単です。同期を使用するタイミングとスレッドを作成するタイミングを理解するには、しばらく時間がかかります。

まず、Java ConcurrencyinPracticeを読む必要があります。

于 2012-08-09T16:15:56.613 に答える
1

ここで複数の質問をしているようです。したがって、まず第一に、絶対に必要でない限り、同期を避けることは確かに良い考えです。

2番目の質問では、値を複数のスレッドから変更できない限り、StringBuilderをStringBufferに、またはその逆に置き換えることも安全です。

于 2012-08-09T16:16:42.543 に答える
0

複数のスレッドが問題を引き起こすとは思わないので、StringBuilder代わりに使用しています。StringBuffer

于 2012-08-09T16:15:24.080 に答える
0

これらのオブジェクト(Vectors、StringBuffers)がスレッド間で共有されていないことを100%確信している場合、または同期されたオブジェクトの選択がスレッドによって駆動されていない場合を除いて、コードベース全体でそれを行うと、さらに分析しなくても自動的に少し危険に聞こえますそもそも安全性分析。

リスクなしでスワップを実行できる単純なケースの1つはローカル変数です。これは、スレッド間で共有できないことは明らかです(それらを返さない限り)。

于 2012-08-09T16:15:39.767 に答える
0

このリンクはそれを最もよく言います:

* http://javahowto.blogspot.com/2006/08/stringbuilder-vs-stringbuffer.html

StringBuilderはJDK1.5で導入されました。StringBuilderとStringBufferの違いは何ですか?javadocによると、StringBuilderは、シングルスレッドでの使用におけるStringBufferの代替として設計されています。簡単に言うと、主な違いは次のとおりです。

  • StringBufferはスレッドセーフになるように設計されており、StringBufferのすべてのパブリックメソッドが同期されます。StringBuilderはスレッドセーフの問題を処理せず、そのメソッドはいずれも同期されません。

  • StringBuilderは、ほとんどの状況でStringBufferよりも優れたパフォーマンスを発揮します。

  • 可能な限り、新しいStringBuilderを使用してください。

私自身の経験から:

  • 深刻な文字列操作の場合は、常にStringBuilderを使用してください(「String」ではありません)。

  • StringBufferを使用する機会は一度もありません(代わりに常に「StringBuilder」を使用します)。

  • 同じ進行中の文字列が複数のスレッドから同時にアクセスされている場合にのみ、「StringBuffer」を検討する必要があります。それでも、代わりに独自のロックを使用する方が簡単/効率的であることがわかるかもしれません。

私見では...

于 2012-08-09T16:16:39.330 に答える
0

複数のスレッドを意識的に作成していない限り、同期されたコレクション(または他のもの)を使用しないことは良い(安全な)経験則ですか?

いいえそうではありません。

意識的に作成しなくても、複数のスレッドが関係する場合があります。たとえば、Swingまたはサーブレットを使用するアプリケーションには、異なるスレッド上のアプリケーションコード間の相互作用の可能性があります。(そして、標準のスレッドプール実装を使用する場合は、明示的にスレッドを作成しないと主張することもできます。)

さらに、同期されたコレクションを使用しても、必ずしもスレッドセーフが得られるとは限りません。

しかし、データ構造を使用する複数のスレッドの可能性がないときに同期されたデータ構造を使用することは(ある程度)無駄であるという意味で正しいです。しかし、ミューテックスが高価だった昔ほど無駄なことはありません。


つまり、「可能な限り新しいStringBuilderを使用してください。」というメッセージが表示されました。知りたいのは、それが可能であることをどのように確認できるかということです。

あなたのコードを理解することによって。StringBuilder他のスレッドで見ることができますか?そうでない場合は、安全に使用できます。StringBuilderそれ以外の場合は、同期の必要性を共有するスレッド。これを行う1つの方法は、を使用することですが、必ずしも適切な同期の粒度が得られるStringBufferとは限りません。

簡単な例を次に示します。

  public String nTimes(String str, int n) {
      StringBuilder sb = new StringBuilder();
      for (int i = 1; i <= n; i++) sb.append(str);
      return sb.toString();
  }

上記では、StringBuilderinsbは別のスレッドからは見えないため、同期する必要はありません。

于 2012-08-09T16:24:40.097 に答える