F#というか.NETにJavaのAtomicBooleanがなかったので実装してみた
タイトルの通り、.NETにはJavaのAtomicBoolean(CAS操作のできるBoolean)が存在しないので、適当に実装してみた。スレッドセーフを保障しつつ、一回だけ処理を走らせたい場合なんかに使うと思う。
実装例
ここの例はF#だけど、Interlockedを使ってるだけなので、C#で書いても同じようなコードになるはず。
open System.Threading type InterlockedBool(?initValue) = let TrueValue = 1L let FalseValue = 0L let toBool x = if x = TrueValue then true else false let toInt64 x = if x then TrueValue else FalseValue let valueRef = defaultArg initValue false |> toInt64 |> ref (* AtomicBoolean#getAndSetと同等 *) member this.Exchange(value) = Interlocked.Exchange(valueRef, toInt64 value) |> toBool (* AtomicBoolean#compareAndSetと同等だが引数の順番が異なる *) member this.CompareExchange(value, comparand) = Interlocked.CompareExchange(valueRef, toInt64 value, toInt64 comparand) |> toBool member this.Read() = Interlocked.Read(valueRef) |> toBool
Exchange()の利用例(一回だけ処理を走らせる)
let isUnprocessed = new InterlockedBool(true) (* 現在の値を取得 *) isUnprocessed.Read() |> printfn "%b" (* Exchange()すると指定した値で上書きつつ、元々格納されていた値が返される *) if isUnprocessed.Exchange(false) then printfn "うごいた!"
CompareExchange()の利用例はぱっと思いつかなかった。