【问题标题】:How can I create a thread lock/synchronization for meaningfully equal objects and prevent parallel execution of the respective threads?如何为有意义的相等对象创建线程锁定/同步并防止相应线程的并行执行?
【发布时间】:2018-09-11 11:41:16
【问题描述】:
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 对象,特定的块也会被同步。我不想要这种行为。

如果我像下面这样获取 customerKey 对象的锁,而不是“this”变量,

同步的(customerKey)

多个线程可以传递不同的 customerKey 对象但具有相同的值,这意味着它们有意义地相等 (customerKeyThread1.equals(customerKeyThread2)) 但对象不同 (customerKeyThread1 != customerKeyThread2)

因此锁定 customerKey 对象也不是一个有效的解决方案。

所以我需要一些逻辑来为一组代码提供同步,不仅为同一个对象而且为有意义的相等对象。我怎样才能达到同样的效果?

【问题讨论】:

  • 你不是在这里找ConcurrentHashMap::getOrDefault吗?
  • 您好,非常感谢您的回复。但我认为这种方法对我来说没有用。您能否详细说明一下您的解决方案?
  • 看来您的getCustomer 需要以线程安全的方式做一件事:如果客户在Map 中,则获取客户 获取新的@ 987654325@。这就是getOrDefault 的用途。如果不是这样,请让我们更清楚您的问题
  • 抱歉,刚刚编辑了原帖。添加了几行例如,如果 2 个线程以两个有意义的相等键并行进入此方法,1)如果我不同步,将不必要地创建两个 Customer 对象。 2)如果我通过锁定“this”对象来进行同步,即使对于具有不同 CustomerKey 对象的线程也会陷入同步
  • 所以我需要一些机制来创建一个 Customer 对象,即使多个线程以有意义相等的键并行出现并且不对具有有意义不相等键的线程进行任何同步

标签: java multithreading synchronization locks


【解决方案1】:

那么在这种情况下你让它变得更简单了(在我看来),只需使用ConcurrentHashMap.computeIfAbsent,因为它记录在:

与指定键关联的当前(现有或计算的)值,如果计算的值为 null,则为 null。

它还说:

整个方法调用都是原子执行的......

所以你可以这样做:

public Customer getCustomer(CustomerKey customerKey) {
    return customerMap.computeIfAbsent(customerKey, x-> new Customer());
}

【讨论】:

    猜你喜欢
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多