0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TypeScriptでDouble Checked Lockを使う

Last updated at Posted at 2025-01-28

Double Checked Lockとは?

Double-checked lockingとは、通常は複数スレッドから参照される変数を高速、かつ安全に初期化するために利用される手法です。

  • 初期化処理は一回しか動かしたくない→ロックが必要
  • 初期化中のインスタンスは利用できない→ロックが必要
  • 初期化完了後はできるかぎり高速に動作させたい→ロックしたくない

ロックが必要だけど、ロックしたくない。この相反する要求を満たすために、ロックをせずにまずは確認を行い、初期化が必要なときにはロックを取得して再度確認を行う。2回確認するのでDouble Checkedと呼ぶわけです。

TypeScriptなら不要では?

通常シングルスレッドで動作するTypeScript環境ですが、非同期処理が存在します。複数の非同期処理から参照される変数を高速、かつ安全に初期化するためにはこの手法が有効になります。

実際のコードは下記のようになります。

export class LazyInitializer<T> {

    protected _target: T | undefined
    protected _synchronizer = new Semaphore(1)

    constructor(protected readonly _factory: () => Promise<T>) {
    }

    async get(): Promise<T> {
        if (this._target !== undefined) {
            return this._target
        }
        await this._synchronizer.synchronized(async () => {
            if (this._target === undefined) {
                this._target = await this._factory()
            }
        })
        // this._target cannot be undefined unless factory returns undefined
        if (this._target === undefined) {
            throw new SynchronizerInvalidError("factory returned undefined")
        }
        return this._target
    }
}

注:TypeScriptには標準でSemaphoreは存在しないので、Semaphoreは別途実装が必要です。
https://qiita.com/tomohisaota/items/88220c5812b1281e0985

自作ライブラリ ya-syn

今回紹介した実装はya-synの実装の一部になっています。

もちろんSemaphoreもあります!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?