Java における StringBuilder と StringBuffer

Susan Sarandon
リリース: 2024-11-18 03:19:02
オリジナル
853 人が閲覧しました

StringBuilder vs StringBuffer in Java

Java では、mutable 文字列 (変更可能な文字列) を操作する場合、StringBuilder と StringBuffer のどちらかを選択する必要がある場合があります。どちらも値の変更が可能な可変クラスですが、スレッドの安全性、パフォーマンス、アプリケーションの点で大きく異なります。ここでは、それらの特性を比較し、それぞれをいつ使用するかを説明するコード例を示します。


主な違い: StringBuilder と StringBuffer

機能 StringBuilder 文字列バッファ
Feature StringBuilder StringBuffer
Mutability Mutable Mutable
Stored in Heap (does not use String Pool) Heap (does not use String Pool)
Thread Safety Not thread-safe Thread-safe
Synchronization Not synchronized Synchronized
Performance Faster due to lack of synchronization Slower due to synchronization overhead
Use Case Single-threaded scenarios Multi-threaded scenarios where thread-safety is required
可変性 変更可能 変更可能 に保存されています ヒープ (文字列プールを使用しません) ヒープ (文字列プールを使用しません) スレッドの安全性 スレッドセーフではありません スレッドセーフ 同期 同期されていません 同期済み パフォーマンス 同期がないため高速 同期オーバーヘッドにより速度が低下する 使用例 シングルスレッドのシナリオ スレッドセーフが必要なマルチスレッドのシナリオ テーブル>

各クラスをさらに詳しく見てみましょう。


1. StringBuilder: シングルスレッド環境の効率的な選択

  • StringBuilder は 可変 クラスです。つまり、コンテンツの変更が可能です。

  • スレッドアンセーフであるため、シングルスレッドのシナリオに最適です。

  • 同期されていません: 同期オーバーヘッドがないため、StringBuilder は StringBuffer よりも高速です。

  • マルチスレッドの制限: 追加の安全対策なしでマルチスレッド環境で StringBuilder を使用すると、競合状態やその他の同時実行の問題が発生する可能性があります。

例: StringBuilder でのスレッドの安全性の実証

この例では、2 つのスレッドを使用して文字を StringBuilder インスタンスに追加します。ただし、同期が欠如しているため、競合状態が発生します:

public class StringBuilderBasics {

    public void threadUnsafe() {
        // Common resource being shared
        StringBuilder builder = new StringBuilder();

        // Thread appending "A" 1000 times
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                builder.append("A");
            }
        });

        // Thread appending "B" 1000 times
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                builder.append("B");
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Result: 1840 (unpredictable)
        System.out.println("Length: " + builder.toString().length());
    }

    public static void main(String[] args) {
        new StringBuilderBasics().threadUnsafe();
    }
}
ログイン後にコピー

説明:

  • スレッドの安全性が確保されていないため、StringBuilder 出力の最終的な長さは予測できません (例: 2000 ではなく 1840 )。

  • これは、両方のスレッドが同時に文字を追加しようとし、上書き または 操作の削除 が発生するために発生します。

要点: StringBuilder はシングルスレッド環境、またはスレッドセーフが外部で処理される場合にのみ使用してください。


2. StringBuffer: マルチスレッド環境向けの安全なオプション

  • StringBuffer は 変更可能であり、その内容の変更が可能です。

  • 同期されているため、スレッドセーフとなります。

  • スレッドセーフが必要なマルチスレッド環境に最適です。

  • パフォーマンス コスト: 同期によりオーバーヘッドが発生するため、StringBuffer は StringBuilder よりも遅い

例: StringBuffer のスレッド セーフティ

これは上記と同じ例ですが、今回は StringBuffer を使用しています:

public class StringBufferBasics {

    public void threadSafe() {
        // Common resource being shared
        StringBuffer buffer = new StringBuffer();

        // Thread appending "A" 1000 times
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                buffer.append("A");
            }
        });

        // Thread appending "B" 1000 times
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                buffer.append("B");
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Result: 2000
        System.out.println("Length: " + buffer.toString().length());
    }

    public static void main(String[] args) {
        new StringBufferBasics().threadSafe();
    }
}
ログイン後にコピー

説明:

  • StringBuffer は、両方のスレッドが安全に追加されることを保証し、予想される長さの 2000 を達成します。

  • 最後の文字列はスレッドセーフですが、スレッドの実行順序が 非決定的であるため、出力は インターリーブ (例: 「AAABBB...」が混在する) になる可能性があります。 🎜>.

要点: データの一貫性が重要であり、同期が必要なマルチスレッド アプリケーションには StringBuffer を使用します。


適切なクラスの選択

StringBuilder と StringBuffer のどちらを選択するかを決定するには、次の点を考慮してください。

  • パフォーマンスが重要でスレッドの安全性が考慮されていないシングルスレッドのシナリオでは StringBuilder を使用します。

  • 変更可能な文字列操作が必要で、競合状態を避けるためにスレッドの安全性が必要なマルチスレッド シナリオでは StringBuffer を使用します。


結論

この比較は、StringBuilder と StringBuffer の間で情報に基づいた選択を行うのに役立ちます。可変性、パフォーマンス、スレッドの安全性のトレードオフを理解すると、Java で文字列を操作する際のより適切な意思決定につながる可能性があります。


関連記事

  • Java の基礎
  • アレイ面接の必需品
  • Java メモリの基礎
  • Java キーワードの基礎
  • Java OOP の基本
  • コレクション フレームワークの基本

コーディングを楽しんでください!

以上がJava における StringBuilder と StringBufferの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート