简体   繁体   English

如何为有意义的相等对象创建线程锁/同步并防止各个线程的并行执行?

[英]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.

相关问题 我该如何重写此主线程-工作线程同步 - How can I rewrite this main thread - worker threads synchronization ExecutorService:在线程中完成同步屏障时如何防止线程饥饿 - ExecutorService: how to prevent thread starvation when synchronization barriers are done in the threads 同步:多个锁-创建锁对象? - Synchronization: multiple locks - create lock objects? 线程同步 - 如何交替执行线程 - Thread Synchronization - How to execute threads alternatively 如何在并行执行上下文中找出我需要的N个线程? - How to figure out N threads I need in a parallel execution context? 有线程调度程序时,如何并行执行线程? - How can threads of execution be running concurrently when there is a thread scheduler? 如何使用可重入锁实现三个线程的同步? - How to achieve synchronization of three threads using reentrant lock? 如何使用线程同步方法进行如下打印? - How Can I print like below using thread synchronization method? 在这种情况下,线程如何同时获得两个对象的锁? - How can a thread acquire lock on two objects simultaneously as in this case? 如何在各自的测试文件夹中为每个测试生成 cucumber.json(我使用的是 Cucumber 5,它使用 Z0F10ECB7756532AE8DAE8CA448 进行并行执行) - How to generate cucumber.json per test in respective test folders (I am using Cucumber 5 which uses TestNG for parallel execution)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM