ホームページ >バックエンド開発 >Golang >Go はコンテキスト固有のデータに対して Java の ThreadLocal を効果的に置き換えることができますか?

Go はコンテキスト固有のデータに対して Java の ThreadLocal を効果的に置き換えることができますか?

DDD
DDDオリジナル
2024-12-21 00:20:09213ブラウズ

Can Go Effectively Replace Java's ThreadLocal for Context-Specific Data?

Go のコンテキスト固有のデータ: Java の ThreadLocal の代替

Go ルーチンを使用する場合、コンテキスト固有のデータにアクセスする機能これは、メトリクスを追跡したり、リクエスト固有の情報に基づいて操作を実行したりするために重要です。 Java でこれを実現するために、現在のスレッドに関連付けられたデータを保存するために ThreadLocal クラスがよく使用されます。

Go は Java の ThreadLocal をエミュレートできますか?

Go は同様の機能を提供しますか? JavaのThreadLocalの仕組みは?答えは簡単ではありません。

代替アプローチ

  • Goroutine Local Storage (gls) パッケージ:
    このサードパーティパッケージには goroutine ローカル ストレージが実装されており、データを特定の goroutine に関連付けることができます。ただし、実装には複雑さがあり、すべてのシナリオに適しているわけではありません。
  • 明示的なコンテキストの受け渡し:
    Go チームは、ゴルーチンに依存するのではなく、コンテキストを関数の引数として明示的に渡すことを推奨しています。ローカルストレージ。このメソッドはより明示的であり、データ共有をより適切に制御できます。

Go のコンテキスト パッケージ

Go のコンテキスト パッケージは、リクエストを渡すためのよりクリーンな方法を提供します。関数とゴルーチンにわたる特定の情報。簡単に作成、伝播、キャンセルできるコンテキスト オブジェクトが提供されます。

リクエスト内のデータベース アクセス時間を測定するには、次のコンテキストを作成できます。期限を設定し、それを引数としてデータベース アクセス関数に渡します:

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

var startTime sync.Map

func getDBAccessTime(ctx context.Context, query string) (time.Duration, error) {
    t := startTime.Load(ctx)
    if t == nil {
        t = time.Now()
        startTime.Store(ctx, t)
    }
    startTimeStamp := t.(time.Time)
    // Database access logic
    return time.Since(startTimeStamp), nil
}

func main() {
    ctx := context.Background()
    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
    defer cancel()
    duration, err := getDBAccessTime(ctx, "SELECT * FROM users")
    fmt.Printf("Database access time: %s\n", duration)
}

コンテキストを明示的に渡すことで、データが確実に共有されるようにすることができます。必要な範囲内でのみ使用でき、その有効期間をより適切に制御できます。

以上がGo はコンテキスト固有のデータに対して Java の ThreadLocal を効果的に置き換えることができますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。