Javaにおけるマルチスレッドと並行処理の文脈で登場するsynchronizedおよびvolatileキーワードは、スレッド間の同期とメモリの可視性を制御するために使用されます。以下にそれぞれのキーワードについて詳しく説明します。
1. synchronized キーワード
synchronized キーワードsynchronizedは、同時に複数のスレッドが同じコードブロックやオブジェクトにアクセスするのを防ぐためのキーワードです。これにより、**排他制御(ミューテックス)**が実現され、**クリティカルセクション(共有資源へのアクセス部分)**においてデータの一貫性が保証されます。
使用例
解説
-
上記の例では、
incrementとgetCountがsynchronizedで保護されています。 -
複数のスレッドが同時に
increment()を呼び出しても、同時に1スレッドしかメソッドに入れないため、countの不整合が防がれます。
synchronizedの種類
-
インスタンスメソッドに付ける:そのインスタンスのロックを取得。
-
静的メソッドに付ける:クラス自体のロックを取得。
-
コードブロックに付ける:任意のオブジェクトをロック対象にできる。
2. volatile キーワード
volatile キーワードvolatileは、変数の可視性を保証するためのキーワードです。これは、1つのスレッドで更新された変数の値が、他のスレッドにも即座に見えるようにするために使います。
使用例
解説
-
通常の変数では、JVMの最適化やCPUキャッシュの影響で、変更が他のスレッドにすぐには伝わらないことがあります。
-
volatileを使うことで、変数の読み書きが主記憶に直接行われるようになり、キャッシュの一貫性の問題を回避できます。
注意点
-
volatileは排他制御は行わないため、インクリメント(count++のような操作)などの複数ステップを伴う操作には適さない。 -
スレッドセーフな読み書きのみが対象(非アトミック操作には
synchronizedが必要)。
synchronizedとvolatileの比較
synchronizedとvolatileの比較| 項目 | synchronized | volatile |
|---|---|---|
| 主な目的 | 排他制御、同期 | 可視性の確保 |
| アトミック操作 | 保証される | 保証されない |
| 性能 | コストが高い(ロックの取得) | 軽量だが限定的 |
| 適用対象 | メソッドやコードブロック | 変数(フィールド)のみ |
| 排他制御 | 可能 | 不可 |
まとめ
-
synchronizedは排他制御に用いられ、同時アクセスによるデータの破壊を防止します。 -
volatileは可視性の問題を解決する軽量な手段ですが、複雑な同期処理には不向きです。 -
両者は目的が異なるため、場面に応じて適切に使い分ける必要があります。
生成日:2025/05/03