Programmingバックエンド開発者

Javaのsynchronizedキーワードの動作、使用するべき状況、誤用によって引き起こされる可能性のある問題を説明してください。

Hintsage AIアシスタントで面接を突破

回答。

synchronizedキーワードは、Javaのマルチスレッドサポートの開始時から存在し、異なるスレッドからのコードブロックやメソッドへの排他的アクセスを保証します。これは、異なるスレッドから共有データに同時にアクセスする際に発生するレースコンディションとデータの不整合といった古典的な問題に対するJavaの回答です。

問題 マルチスレッド労働の際には、操作の「アトミック性」を確保し、オブジェクトの状態の矛盾した変更を防ぐ必要があります。synchronizedを誤って使用すると、デッドロック、パフォーマンスの低下、またはモニターオブジェクトの不正な選択による同期の欠如が引き起こされる可能性があります。

解決策 synchronizedキーワードを使用して、1つのスレッドだけが同時にその部分を実行することを保証する必要があります。シンクロナイザオブジェクトを慎重に選択し、長いクリティカルセクションを避け、より複雑なタスクにはjava.util.concurrentパッケージの特別なクラスを使用するべきです。

コードの例:

public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } } // 別のオブジェクトでコードの一部だけを同期: private final Object lock = new Object(); public void complexIncrement() { synchronized (lock) { // クリティカルセクション count++; } }

主な特徴:

  • synchronizedは選択された「モニター」に対して他のスレッドからのコードアクセスをブロックします。
  • メソッド全体または特定のブロックのみを同期化することができます。
  • 同期は強力ですが、リスクのあるツールです(デッドロック、パフォーマンス)。

トリック質問。

synchronizedメソッドとsynchronizedブロックの違いは何ですか?

synchronizedメソッドはオブジェクト(またはstaticメソッドの場合はクラス)の「モニター」をブロックしますが、synchronizedブロックは明示的にモニターオブジェクトを指定できるため、より柔軟性があります。

一つのオブジェクトで異なるメソッドをsynchronizedした場合、どうなりますか?

両方のメソッドがsynchronizedでマークされている場合(staticでない限り)、両方とも自身のオブジェクト(this)をモニターとして使用します。一方のスレッドがどちらかのメソッドに入ることができない限り、他方のメソッドには入れません。

staticメソッドと通常のメソッドを同期できますか?それらはお互いにどうブロックされますか?

staticメソッドはクラスそのもの(Classオブジェクト)のモニターを使用し、通常のメソッドはインスタンスオブジェクトを使用します。したがって、static synchronizedメソッドと通常のsynchronizedメソッドはお互いをブロックしません。

一般的なエラーとアンチパターン

  • 不正なオブジェクト(例えば、Stringやプールからのオブジェクト)での同期
  • 長すぎるまたは不明瞭なクリティカルセクションでの低下
  • 待機のループまたはデッドロック
  • java.util.concurrentの現代的な代替手段の代わりにsynchronizedを乱用すること

より実用的な例

ネガティブケース

開発者は異なるオブジェクトのメソッドを同期しますが、同じStringをモニターとして使用します。その結果、パフォーマンスが低下し、文字列がプールから再利用されることによる「偶発的な」デッドロックが発生します。

利点:

  • コードが短く、迅速に記述できる

欠点:

  • デッドロックのリスクが高い
  • デバッグが難しい
  • パフォーマンスの急激な低下

ポジティブケース

クラス内部でのみ作成されたプライベートのfinalオブジェクトを使用して同期化し(private final Object lock)、クリティカルセクションは最小限の時間を要する。

利点:

  • 正しい動作の保証
  • 最小限のオーバーヘッド
  • 読みやすく、保守が容易

欠点:

  • 規律と経験が必要
  • 初心者の開発者には必ずしも明らかではない