简体   繁体   English

concurrenthashmap java

[英]concurrenthashmap java

This seems wrong. 这似乎是错的。

        static ConcurrentHashMap k; //multiple threads have access to k
         X o = k.get("LL");
         o.a = 6;

If multiple threads access k concurrently, and get k("LL"), then update (oa = #) without k.put("ll",o), without synchronizing on 'o', or on 'k' what happens? 如果多个线程同时访问k,并得到k(“LL”),那么更新(oa =#)而没有k.put(“ll”,o),没有同步'o',或'k'会发生什么?

The ConcurrentHashMap guarantees that getting a value is atomic, but it can't control what you do with the values you get from it. ConcurrentHashMap保证获取值是原子的,但它无法控制您使用从中获取的值。 Modifying values in the hashmap is fine from the ConcurrentHashMap's view but may still not result in the behaviour you want. 在ConcurrentHashMap的视图中修改hashmap中的值很好,但可能仍然不会导致您想要的行为。 To be sure about thread-safety you need to consider exactly what each thread that has access to it does. 为了确保线程安全,您需要准确考虑每个有权访问它的线程。

Putting the value back in the ConcurrentHashMap seems redundant and doesn't make the whole operation any safer. 将值放回ConcurrentHashMap似乎是多余的,并不会使整个操作更安全。 You're already modifying the object outside of any synchronization. 您已经在任何同步之外修改对象。

Additional synchronization may be necessary, but I can't tell for sure without seeing more context. 可能需要额外的同步,但如果没有更多的上下文,我无法确定。

A ConcurrentMap has conditional operations that guarantee atomic insert/removal and replacement of key/value pairs. ConcurrentMap具有条件操作,可保证原子插入/删除和替换键/值对。 Additionally, accessing a ConcurrentMap creates a happens-before relationship so you can make certain guarantees about the ordering of your code. 此外,访问ConcurrentMap会创建一个before-before关系,因此您可以对代码的排序做出某些保证。

In the code presented, the line: 在提供的代码中,行:

X o = k.get("LL");

accesses the current X value for the key "LL". 访问键“LL”的当前X值。 The next line modifies the a property. 下一行修改a属性。 Without knowing the implementation of X, this is Java so we know that there is no method call here. 在不知道X的实现的情况下,这是Java,所以我们知道这里没有方法调用。 If (and only if) the a property is marked as volatile then some subsequent code accessing the X at "LL" will see the a value as 6. If it isn't volatile then there are no guarantees at all. 如果 (并且仅当)a属性被标记为volatile,那么在“LL”处访问X的一些后续代码将看到a值为6.如果它不是volatile,则根本没有保证。 They will probably see 6, particularly on an SMP x86 box, with not many threads doing much at the time. 他们可能会看到6,特别是在SMP x86盒子上,当时没有多少线程做得很多。 In production, on a big NUMA box, they are less likely to. 在生产中,在一个大的NUMA盒子上,他们不太可能。 Mutability brings with it all sorts of complications and difficulty. 可变性带来了各种复杂性和困难。

Generally, you'll find it is easier to reason about the state the map is in if you use immutable keys AND values. 通常,如果使用不可变键和值,您会发现更容易推断映射所处的状态。

Simply speaking: 简单地说:

  o.a=6

is an atomic operation, all the threads will compete, and the last thread setting it will "win", overwriting the value. 是一个原子操作,所有线程都将竞争,最后一个线程设置它将“赢”,覆盖该值。

More specifically, the ConcurrentHashMap only guarantees that the link between a key and its associated value is handled taking multiple threads into account - ie put and get are atomic . 更具体地说,ConcurrentHashMap仅保证在考虑多个线程的情况下处理密钥与其关联值之间的链接 - 即put和get是原子的

This does not prevent any thread from modifying attributes of the value once it gets a reference to it! 这不会阻止任何线程一旦获得对它的引用就修改该值的属性!

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

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