なぜStringBuilderのスレッドセーフ

私たちは、StringBuilderのとStringBufferのCHARながら、Stringクラスで同じことを達成するために内部のStringBuilderとStringBufferのを知ってほしい最後のchar配列が変更された内側に、文字列を格納するchar配列により、Stringクラスが異なっている、不変です配列は可変です。

どのような問題が生じてしまうまず、StringBuilderオブジェクトをマルチスレッドコードの一部を通して見てみましょう

 

私たちは、StringBuilderオブジェクトにそれぞれ1000サイクルは、内部の文字を追加し、このコードは10個のスレッドを作成します見ることができます。通常の状況下では、出力コードは10000である必要がありますが、実際どのような出力がそれを実行するのでしょうか?

 

 私たちは、予想より10,000以下、「9326」の出力を見て、また(例外は今や必ずしもではない)は、ArrayIndexOutOfBoundsExceptionの例外がスローされます。

 

1.なぜ期待値と出力値が同じではありません

私たちは、StringBuilderの2つのメンバ変数を見て(両方のメンバ変数が実際に内部AbstractStringBuilderで定義されている、のStringBuilderとStringBufferのAbstractStringBuilder継承されています)

 

StringBuilderのはappend()メソッドを見てください:

 

 親クラスAbstractStringBuilderコールアペンドのStringBuilderのはappend()メソッド()メソッド

 

 

コードが働いたかどうか私たちの最初の第五及び第六行は何ですか、7行目で直接見て、カウント+ = lenがアトミック操作ではありません。10のカウント値は、現時点では想定され、lenが1であり、同時にカウント値を取得するために、7行目を実行するための2つのスレッドは、カウントに加えの割当結果を実行した後、10であるので、後者の二つのスレッドの実装代わりに、12の11のカウント値、。これは万点の理由よりも小さい理由は、テストコードの出力値です。

2.なぜ、ArrayIndexOutOfBoundsExceptionが例外をスローします。

我々はソースコードの5行目の追記()メソッドAbstractStringBuilder振り返る、ensureCapacityInternal()メソッドは、char配列のコールexpandCapacity()メソッドをオーバーフローした場合、新たな文字列を保持することができ、元のchar配列のStringBuilderオブジェクトの容量を確認することです拡張。

 

 新しい拡張論理アレイ新しい文字、新しいアレイのチャー容量は次いでSystem.arryCopy()、最後にポインタを介して、新たな配列char配列プラス2倍2にアレイの元の内容をコピーする関数であります新しいchar配列。

 

 Arrys.copyOf()メソッド

 

 次のように、char配列StringBuilderオブジェクトの内部に内容をコピー対象文字列char配列であるソースコードの6行目の追記()メソッド、AbstractStringBuilder

 

 GetCharsは()メソッド

 

 コピープロセスは以下の通り:

 

 

 

 

 

 

スレッド1は、カウント値が6であり、そして実行char配列のコピーは、ArrayIndexOutOfBoundsException例外がスローされたときに取得するstr.getChars 6行目()メソッドを継続します。

これまでのところ、StringBuilderのはなぜ不安を超える分析されています。我々がテストした場合、出力StringBufferオブジェクトへのStringBuilderオブジェクトコードは何をしますか?

 

もちろん、それは10 000の出力であります!

だから何のStringBufferはスレッドセーフを保証することを意味しますか?あなたが知っているのStringBufferのappend()メソッドを介してクリックしてください問題。

 

おすすめ

転載: www.cnblogs.com/weirdo-lenovo/p/11437885.html