【Kotlin/Android】synchronized/@Synchronized/Mutexでスレッドセーフ(排他制御)

この記事からわかること
- Android Studio/Kotlinでスレッドセーフ(排他制御)を実装するには?
- synchronizedの使い方
- @Synchronizedアノテーションの使い方
- Coroutinesで使うMutexの使い方
\ アプリをリリースしました /
環境
- Android Studio:Meerkat
- Kotlin:2.0.21
- Mac M1:Sequoia 15.4
スレッドセーフ(排他制御)な実装
Kotlinで複数のスレッドからの同時アクセスを防ぐための手段はいくつか存在します。今回はその中でもsynchronized
ブロックや@Synchronized
アノテーションの使い方をまとめていきます。
またMutex
というCoroutines用の排他制御の使い方も一緒に解説しておきます。
synchronizedブロック
synchronized
ブロックは同時に1つのスレッドしか実行できないようにコードを保護することができるブロックです。引数lock
にはロック制御対象となる任意の型のオブジェクトを渡し、引数block
にスレッドセーフで行いたい処理を渡します。
例えば「スレッドセーフなカウンター」を実装したい場合は以下のようになります。
ただこれならAtomicInteger
を使用した方がわかりやすいかもしれません。
synchronized
ブロックの特徴はロック用のオブジェクトを指定できるところです。これにより異なるメソッド間でも同一のロック機構を使用してスレッドセーフな処理を定義することが可能になっています。そのため異なるロックオブジェクトを使用している場合は競合が発生する可能性があるので注意してください。
@Synchronizedアノテーション
@Synchronized
アノテーションはインスタンス単位でスレッドセーフな処理を定義するためのアノテーションです。先ほどはロック対象が任意のオブジェクトでしたが、こちらはthis
(自身)になるため、同一のインスタンスを使用している箇所に限りスレッドセーフに扱うことが可能になります。
Mutex
先に紹介したsynchronized
/@Synchronized
はCoroutinesではうまく動作しないようでMutex
というCoroutines用の排他制御機構が用意されています。スレッドセーフにするためにはwithLock
を使用します。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。