Как я могу создать блокировку / синхронизацию потоков для значимо равных объектов и предотвратить параллельное выполнение соответствующих потоков? - PullRequest
0 голосов
/ 11 сентября 2018
private Map<CustomerKey, Customer> customerMap = new ConcurrentHashMap<CustomerKey, Customer>();

public Customer getCustomer(CustomerKey customerKey)
{   
    Customer customer = customerMap.get(customerKey);
    if(null == customer)
    {
        synchronized(this)
        {
            customer = customerMap.get(customerKey); // Added line
            if(null == customer)
            {
                customer = new Customer();
                customerMap.put(customerKey, customer); // Added line
            }
        }
    }
    return customer;
}

Так мы обычно делаем блокировку уровня объекта.

В этом примере блокировка уровня объекта применяется независимо от значения объекта customerKey.Таким образом, даже для различных объектов customerKey конкретный блок будет синхронизирован.Я не хочу, чтобы это поведение.

Вместо переменной "this", если я получаю блокировку на объекте customerKey, как показано ниже,

synchronized (customerKey)

Несколько потоков могут передавать разные объекты customerKey, но с одинаковым значением, что означает, что они значимо равны (customerKeyThread1.equals (customerKeyThread2)), но не с одинаковыми объектами (customerKeyThread1! = CustomerKeyThread2)

Таким образом, блокировка объекта customerKeyтакже не является допустимым решением.

Поэтому мне нужна логика, которая обеспечивает синхронизацию для набора кода не только для одного и того же объекта, но и для значимо равных объектов .Как я могу добиться того же?

1 Ответ

0 голосов
/ 11 сентября 2018

Ну, вы сделали это проще в таком случае (мне кажется), просто используйте ConcurrentHashMap.computeIfAbsent, как это задокументировано с помощью:

текущее (существующее или вычисленное) значение, связанное с указанным ключом, или ноль, если вычисленное значение равно нулю.

Также сказано, что:

Весь вызов метода выполняется атомарно ....

Чтобы вы могли сделать:

public Customer getCustomer(CustomerKey customerKey) {
    return customerMap.computeIfAbsent(customerKey, x-> new Customer());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...