VB.NETの極み:ReaderWriterLockSlimで並行処理のボトルネックを粉砕する
こんにちは。長年、複雑な業務システムの裏側をVB.NETで支えてきたエンジニアです。
皆さんが普段書いているVB.NETのコード、もし「とりあえず `SyncLock` で囲んでおけば安全」と考えているなら、それはパフォーマンスの砂漠に水を撒いているのと同じかもしれません。
今日は、中級者から一歩先へ進みたいあなたへ、「読み取り頻度が高く、書き込みが稀」なデータ構造を扱う際に必須となる、プロ仕様の同期制御`ReaderWriterLockSlim`を伝授します。
—
1. なぜ「SyncLock」だけではダメなのか?
VB.NETでスレッドの衝突を防ぐとき、真っ先に思い浮かぶのが `SyncLock` ですよね。
‘ 悪い例:読み取りでも書き込みでも、とにかく全員待ちぼうけ
SyncLock _lockObject
‘ 読み取り処理…
End SyncLock
`SyncLock` は非常に強力ですが、「読み取りスレッド」同士すら互いを排除してしまいます。100人が同時に「値を見たいだけ」なのに、順番待ちをさせる。これは、オフィスでたった一つの資料を全員が回し読みするような非効率さです。
ここで登場するのが `ReaderWriterLockSlim` です。これは「読み取り中は全員OK、書き込み中は誰にも邪魔させない」という、マルチタスクの交通整理を行ってくれる賢いクラスです。
—
2. ReaderWriterLockSlim の賢いルール
このクラスは、スレッドに対して「許可証」を発行します。
- 読み取りロック (EnterReadLock): 「見るだけですよ」という許可。他の読み取りスレッドも同時に入れます。
- 書き込みロック (EnterWriteLock): 「書き換えます!」という許可。他の誰も入れません(読み取りスレッドもストップ)。
図解的イメージ
- 読み取り時: ゲートが全開。何人でも通れる。
- 書き込み時: ゲートを完全に封鎖。誰も通れない。
—
3. 実践:スレッドセーフなデータ保持クラス
では、実際にプロの現場で使えるコードを見てみましょう。
Imports System.Threading
Public Class ThreadSafeCache(Of T)
‘ ReaderWriterLockSlim インスタンスを作成
Private ReadOnly _lock As New ReaderWriterLockSlim()
Private _value As T
‘ 読み取りメソッド
Public Function GetValue() As T
_lock.EnterReadLock() ‘ 読み取りロック開始
Try
Return _value
Finally
_lock.ExitReadLock() ‘ 必ず解除!
End Try
End Function
‘ 書き込みメソッド
Public Sub SetValue(newValue As T)
_lock.EnterWriteLock() ‘ 書き込みロック開始(ここが呼ばれると他は待機)
Try
_value = newValue
Finally
_lock.ExitWriteLock() ‘ 必ず解除!
End Try
End Sub
End Class
【重要】ここがプロのこだわりポイント
1. `Try…Finally` ブロックは必須です。
万が一処理中にエラーが発生しても、ロックを確実に解除しなければなりません。これを忘れると、アプリ全体が永久にフリーズ(デッドロック)します。
2. `IDisposable` パターンを検討する。
このクラスを使い終わる際には `_lock.Dispose()` を呼ぶのが作法です。メモリリークを防ぐための鉄則ですね。
—
4. 陥りやすい罠:再帰呼び出しの恐怖
`ReaderWriterLockSlim` を使う際、「ロック中に同じスレッドがもう一度ロックを取りに行く」と、標準設定では例外が発生します。
もし再帰的に呼び出す必要がある場合は、コンストラクタで設定を変更してください。
`New ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion)`
ただし、基本的には「ロックは最小限の範囲で、再帰は避ける」のが設計の美学です。
—
最後に:なぜ「今」これを学ぶのか
VB.NETは、モダンな.NET Core / .NET 5以降の環境でも非常に強力に動作します。特にクラウドネイティブなサービスや、高速なデータ処理が求められる業務アプリケーションにおいて、スレッドをどう扱うかは「エンジニアの格」を分けるポイントです。
「ただ動くコード」から「負荷に負けないコード」へ。
今回の `ReaderWriterLockSlim` を習得すれば、あなたの書くVB.NETは、これまでとは比べ物にならないほど堅牢で速いものになるはずです。
もし分からないことがあれば、またいつでも聞きに来てください。応援しています!
