ホームページ >Java >&#&チュートリアル >Java で文字列オブジェクトを同期するのはなぜ悪い考えなのでしょうか?

Java で文字列オブジェクトを同期するのはなぜ悪い考えなのでしょうか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-27 21:51:12455ブラウズ

Why Is Synchronizing on String Objects in Java a Bad Idea?

Java の文字列オブジェクトの同期

概要:

マルチスレッド Java アプリケーションの場合、コード ブロックの同期は、正しく一貫した動作を保証するために非常に重要です。ただし、同期するオブジェクトの選択は、コードの正確さとパフォーマンスの両方に影響を与える可能性があります。この記事では、一般的ではあるが問題が発生する可能性がある String オブジェクトの同期の結果について説明します。

String オブジェクトと ID:

プリミティブ型とは異なり、String オブジェクトは不変であり、参照により実行されます。同じ値を持つ 2 つの String オブジェクトは同一に見えますが、メモリ内では必ずしも同じオブジェクトであるとは限りません。

文字列の同期に関する問題:

複数のスレッドが存在する場合同じ String オブジェクト上で同期すると、その同期によって保護されたコード ブロックへのアクセスが効果的にシリアル化されます。ただし、キー String オブジェクトがプログラム内で複数回作成される場合、参照の不一致により、各スレッドがブロックへの排他的アクセス権があると誤って認識する可能性があります。

同期の例:

次のコード例を考えてみましょう。これは、文字列を使用してキャッシュへのアクセスを同期しようとします。 key:

private SomeData[] getSomeDataByEmail(WebServiceInterface service, String email) {
    final String key = "Data-" + email;
    synchronized(key) {
        // ... //
    }
    return data;
}

この例では、getSomeDataByEmail の各呼び出しで一意の String キーが使用されていますが、同じ String オブジェクトを参照していないため、複数のスレッドが同期ブロックに入る可能性があります。

解決策 1: 文字列キーをインターニングする

解決策の 1 つは次のとおりです。キー String オブジェクトに対して intern() メソッドを使用します。このメソッドにより、特定の値を持つ String のインスタンスが JVM 内に 1 つだけ存在することが保証されます。インターンされたキーで同期することにより、すべてのスレッドが同じオブジェクトを参照していることが効果的に保証されます。

解決策 2: ロック オブジェクトを使用する

より堅牢な解決策は、次のとおりです。キーごとに専用のロック オブジェクトを作成します。スレッドはキー自体で同期するのではなく、キーに関連付けられたロックを取得します。このアプローチでは、キー インスタンスの数に関係なく、一貫した同期ポイントが提供されます。

結論:

String オブジェクトを誤って作成すると、そのオブジェクトを同期すると同時実行の問題が発生する可能性があります。複数回。信頼性の高いスレッドの安全性を確保するには、インターンされた String キーを使用するか、キーごとに専用のロック オブジェクトを実装することを検討してください。オブジェクトの同期に対する選択の影響を理解することは、効率的で正しいマルチスレッド Java コードを開発するために非常に重要です。

以上がJava で文字列オブジェクトを同期するのはなぜ悪い考えなのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。