【发布时间】: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