[英]How can I create a thread lock/synchronization for meaningfully equal objects and prevent parallel execution of the respective threads?
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;
}
This is how we usually do object level locking.这就是我们通常进行对象级锁定的方式。
In this example, object level locking is applied irrespective of the value of the customerKey object.在此示例中,无论 customerKey 对象的值如何,都会应用对象级锁定。 So even for different customerKey objects, the particular block will be synchronized.
因此,即使对于不同的 customerKey 对象,特定块也会同步。 I don't want this behavior.
我不想要这种行为。
Instead of "this" variable, if I acquire lock on customerKey object like below,而不是“这个”变量,如果我获取像下面这样的 customerKey 对象的锁,
synchronized(customerKey)同步(客户密钥)
Multiple threads can be passing different customerKey objects but with same value which means they are meaningfully equal (customerKeyThread1.equals(customerKeyThread2)) but not same objects (customerKeyThread1 != customerKeyThread2)多个线程可以传递不同的 customerKey 对象但具有相同的值,这意味着它们有意义地相等 (customerKeyThread1.equals(customerKeyThread2)) 但不相同的对象 (customerKeyThread1 != customerKeyThread2)
So locking at customerKey object is also not a valid solution.所以锁定 customerKey 对象也不是一个有效的解决方案。
So I need some logic which provides synchronization for a set of code not only for same object but also for meaningfully equal objects .所以我需要一些逻辑来为一组代码提供同步,不仅为同一个对象,而且为有意义的相等对象。 How can I achieve the same?
我怎样才能达到同样的目标?
Well you made it simpler in such a case (it seems to me), just use ConcurrentHashMap.computeIfAbsent
as it is documented with:那么你在这种情况下使它更简单(在我看来),只需使用
ConcurrentHashMap.computeIfAbsent
因为它记录在案:
the current (existing or computed) value associated with the specified key, or null if the computed value is null.
与指定键关联的当前(现有或计算出的)值,如果计算出的值为空,则为空。
It also says that:它还说:
The entire method invocation is performed atomically....
整个方法调用以原子方式执行....
So you could do:所以你可以这样做:
public Customer getCustomer(CustomerKey customerKey) {
return customerMap.computeIfAbsent(customerKey, x-> new Customer());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.