简体   繁体   English

以下实现线程是否安全?

[英]Is the following implementation thread safe?

I have a java thread safe map which stores String to Object mappings: 我有一个java线程安全映射,它存储String到Object映射:

ConcurrentHashMap<String, MyObject> map = new ConcurrentHashMap<>();

Here MyObject is a user defined class. 这里MyObject是用户定义的类。 Now consider the following method: 现在考虑以下方法:

public void replace(String key, MyObject o) {
    MyObject m = map.get("somekey");
    synchronized(m) {
        // Modify some internal components of m
        // and some other objects related to m
    }
}

My intention here is I want to maximise performance by not putting a lock on the whole class but only on threads that try to access the same key in the map. 我的意图是我希望通过不对整个类进行锁定来最大化性能,但仅限于尝试访问地图中相同键的线程。 Basically every time an entry is replaced in the map (not added) this part of the code gets executed. 基本上每次在地图中替换一个条目(未添加)时,这部分代码就会被执行。 Something like: 就像是:

public void put(String key, MyObject o) {
    if (map.putIfAbsent(key, o) == null){ //do something
    }
    else {
        replace(key, o);
    }
}

For all practical purposes we can assume that this is the only method through which a reference to MyObject can be changed. 出于所有实际目的,我们可以假设这是可以更改对MyObject的引用的唯一方法。 Is this implementation thread safe? 这个实现线程安全吗?

Is the following implementation thread safe? 以下实现线程是否安全?

It depends on how you access and modify your instances of MyObject in your code, if you always access and modify a given instance of MyObject within a synchronized block using this MyObject instance as object's monitor then yes it would be thread safe, otherwise it won't be. 这取决于您如何在代码中访问和修改MyObject实例,如果您始终使用此MyObject实例作为对象的监视器访问和修改同步块中的MyObject的给定实例,那么它将是线程安全的,否则它赢了是的。


Your put method is not thread safe as putIfAbsent and replace are not executed atomically which could lead to race condition issues , use merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) to do the exact same thing but atomically as next: 你的put方法不是线程安全的,因为putIfAbsentreplace不是原子地执行的,这可能导致竞争条件问题 ,使用merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)来做完全相同的事情,但原子上下一个:

public void put(String key, MyObject o) {
    map.merge(
        key, o,
        (v1, v2) -> {
            // Modify some internal components of v1
            // and some other objects related to v1
            return v2;
        }
    );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM