アプリケーションにスレッドが1つしかないとします。使用してStringBuffer
いるので、何が問題なのですか?
StringBuffer
つまり、同期によって複数のスレッドを処理できる場合、単一のスレッドで作業する場合の問題は何ですか?
なぜStringBuilder
代わりに使用するのですか?
アプリケーションにスレッドが1つしかないとします。使用してStringBuffer
いるので、何が問題なのですか?
StringBuffer
つまり、同期によって複数のスレッドを処理できる場合、単一のスレッドで作業する場合の問題は何ですか?
なぜStringBuilder
代わりに使用するのですか?
StringBuffers
スレッドセーフです。つまり、アクセスを制御するための同期メソッドがあり、一度に1つのスレッドだけがStringBufferオブジェクトの同期コードにアクセスできます。したがって、StringBufferオブジェクトは、複数のスレッドが同じStringBufferオブジェクトに同時にアクセスしようとしている可能性があるマルチスレッド環境で一般的に安全に使用できます。
StringBuilder's
アクセスは同期されないため、スレッドセーフではありません。同期されていないため、StringBuilderのパフォーマンスはStringBufferよりも優れている可能性があります。したがって、シングルスレッド環境で作業している場合は、StringBufferの代わりにStringBuilderを使用すると、パフォーマンスが向上する可能性があります。これは、StringBuilderローカル変数(つまり、メソッド内の変数)など、1つのスレッドのみがStringBuilderオブジェクトにアクセスする他の状況にも当てはまります。
だからStringBuilder
、
これをチェックしてください:
StringBuilderは同期されていない(スレッドセーフ)ため、(わずかに)少し高速になるはずです。
非常に重いアプリケーションの違いに気付くでしょう。
StringBuilderクラスは、同じ操作をすべてサポートするため、通常はこれよりも優先して使用する必要がありますが、同期を実行しないため、より高速です。
http://download.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html
複数のスレッドでStringBufferを使用することはほとんど役に立たず、実際にはほとんど起こりません。
次のことを考慮してください
Thread1: sb.append(key1).append("=").append(value1);
Thread2: sb.append(key2).append("=").append(value2);
各追加は同期されますが、スレッドはいつでも前かがみになる可能性があるため、次の組み合わせなどを使用できます。
key1=value1key2=value2
key1key2==value2value1
key2key1=value1=value2
key2=key1=value2value1
これは、一度に行全体を同期することで回避できますが、これは、StringBuilderの代わりにStringBufferを使用するという点を打ち負かします。
正しく同期されたビューがある場合でも、行全体のスレッドローカルコピーを作成するよりも複雑です。たとえば、StringBuilderやログ行を一度にWriterなどのクラスに作成します。
StringBuffer
シングルスレッドアプリケーションでは間違いではありません。と同じように機能しStringBuilder
ます。
唯一の違いは、すべての同期メソッドを使用することで追加される小さなオーバーヘッドです。これは、シングルスレッドアプリケーションでは利点がありません。
私の意見では、コンパイラが連結を含むコードをコンパイルするときに(そして今は)使用することが主な理由です。そのような場合、同期は必要なく、それらの場所をすべて非同期に置き換えると、パフォーマンスがわずかに向上します。 。StringBuilder
StringBuffer
StringBuilder
String
StringBuilder
StringBuilder
メソッドが同期されていないため、パフォーマンスが向上します。
したがって、文字列を同時に作成する必要がない場合(とにかく、これはかなり非典型的なシナリオです)、不要な同期オーバーヘッドを「支払う」必要はありません。
これは皆さんに役立ちます。BeStraightBuilderはBufferよりも高速です。
public class ConcatPerf {
private static final int ITERATIONS = 100000;
private static final int BUFFSIZE = 16;
private void concatStrAdd() {
System.out.print("concatStrAdd -> ");
long startTime = System.currentTimeMillis();
String concat = new String("");
for (int i = 0; i < ITERATIONS; i++) {
concat += i % 10;
}
//System.out.println("Content: " + concat);
long endTime = System.currentTimeMillis();
System.out.print("length: " + concat.length());
System.out.println(" time: " + (endTime - startTime));
}
private void concatStrBuff() {
System.out.print("concatStrBuff -> ");
long startTime = System.currentTimeMillis();
StringBuffer concat = new StringBuffer(BUFFSIZE);
for (int i = 0; i < ITERATIONS; i++) {
concat.append(i % 10);
}
long endTime = System.currentTimeMillis();
//System.out.println("Content: " + concat);
System.out.print("length: " + concat.length());
System.out.println(" time: " + (endTime - startTime));
}
private void concatStrBuild() {
System.out.print("concatStrBuild -> ");
long startTime = System.currentTimeMillis();
StringBuilder concat = new StringBuilder(BUFFSIZE);
for (int i = 0; i < ITERATIONS; i++) {
concat.append(i % 10);
}
long endTime = System.currentTimeMillis();
// System.out.println("Content: " + concat);
System.out.print("length: " + concat.length());
System.out.println(" time: " + (endTime - startTime));
}
public static void main(String[] args) {
ConcatPerf st = new ConcatPerf();
System.out.println("Iterations: " + ITERATIONS);
System.out.println("Buffer : " + BUFFSIZE);
st.concatStrBuff();
st.concatStrBuild();
st.concatStrAdd();
}
}
Output
run:
Iterations: 100000
Buffer : 16
concatStrBuff -> length: 100000 time: 11
concatStrBuild -> length: 100000 time: 4
concatStrAdd ->
マニッシュ、StringBufferインスタンスで動作しているスレッドは1つだけですが、そのメソッドのいずれかが呼び出されるたびに、StringBufferインスタンスのモニターロックを取得および解放する際にオーバーヘッドが発生します。したがって、StringBuilderは、シングルスレッド環境での推奨される選択肢です。
オブジェクトを同期するには莫大なコストがかかります。プログラムをスタンドアロンエンティティと見なさないでください。概念を読んで、質問の詳細で述べたような小さなプログラムに適用する場合は問題ありません。システムを拡張するときに問題が発生します。その場合、シングルスレッドプログラムは他のいくつかのメソッド/プログラム/エンティティに依存している可能性があるため、同期されたオブジェクトはパフォーマンスの点で深刻なプログラミングの複雑さを引き起こす可能性があります。したがって、オブジェクトを同期する必要がないと確信している場合は、StringBuilderを使用する必要があります。これは、優れたプログラミング手法です。最後に、スケーラブルで高性能なシステムを作成するためのプログラミングを学びたいので、それを行う必要があります。