ソナー エラー プロンプトが表示される場合は、代わりに新しい「オブジェクト」で同期してください。ID をロックとして使用してください


    public void synchronizedMethod(Integer id) {
    
    
        synchronized (id) {
    
    
            // Code to be synchronized
        }
    }

エラー分析

Synchronize on a new "Object" instead.
プリミティブ ラッパー (整数、long、ブール値など) はオートボックス化によって作成される可能性があり、Sonar はこれを危険であるとみなしているため、同期は行わないでください。synchronized ステートメントで使用されるロック オブジェクトは、同期されるすべてのスレッドにわたって一定である必要があるため、これは危険です。プログラム ロジックで再利用される可能性のある動的オブジェクトは、簡単に同期エラーを引き起こす可能性があります。したがって、ベスト プラクティスは、Object をインスタンス化し、同期のみに使用される特別なロック オブジェクトを作成することです。

まず、Sonar のソリューションを見てみましょう。

ここに画像の説明を挿入します

彼女が定数オブジェクトを要求していることがわかりますが、それは明らかに私が望んでいることではありません。私が望んでいるのは、異なる ID の入力が非同期であり、同じ ID のみがロックされることです。

最終的解決

ID をロックとして使用するには、Java でカスタム クラスを作成して ID を保存し、それをモニターとして同期します。以下に例を示します。

import java.util.HashMap;
import java.util.Map;

public class SynchronizationExample {
    
    
    private Map<Integer, Object> locks = new ConcurrentHashMap<>();

    public void synchronizedMethod(Integer id) {
    
    
        synchronized (getLock(id)) {
    
    
            // 需要同步的代码块
        }
    }

    private Object getLock(Integer id) {
    
    
        locks.putIfAbsent(id, new Object());
        return locks.get(id);
    }
}

この例では、 を使用して、HashMap各 ID に関連付けられたロック オブジェクトを保存します。synchronizedMethodこのメソッドは ID パラメータを受け取り、locksマップから取得した対応するロック オブジェクトを使用してコード ブロックを同期します。

getLockHashMapメソッドは、 のメソッドを使用して、ID ごとに一意のロック オブジェクトが確実に作成されるようにしますputIfAbsent指定された ID に対応するロック オブジェクトがマップ内にlocksない場合は、新しいロック オブジェクトが作成され、マップに保存されます。同じ ID の場合、後続の呼び出しでは、getLock以前に作成されたロック オブジェクトが返されます。

ID をlocksマップのキーとして使用すると、特定のロックを各 ID に関連付けることができ、すべての ID にわたるのではなく、各 ID の同期を確保できます。

カスタム オブジェクトをロックとして使用する場合は、潜在的な同時実行性の問題を回避するために、基になるデータ構造にアクセスして変更するときにスレッドの安全性を確保してください。

おすすめ

転載: blog.csdn.net/qq_39017153/article/details/132167359