Java Memory Model, ConcurrencyHashMap and guarantee of iterator

ยอดดู 191 ครั้ง
ข้ามไปที่ข้อความที่ยังไม่อ่านรายการแรก

r r

ยังไม่อ่าน,
12 ก.ย. 2565 08:30:5912/9/65
ถึง mechanical-sympathy
Hello,
let's look for the following piece of code:

c = new ConcurrentHashMap<Integer, Boolean>();
T1:  
    c.put(1, true);
    for (Boolean b : c.values()) {
        print(b);
    }
T2:  
    c.put(2, true);
    for (Boolean b : c.values()) {
        print(b);
    }

Is it guaranteed by JMM that any thread (T1 or T2) prints true, true?
To put it in another way, is it guaranteed that T1 or T2 observes both c.put?

If yes / no, why?
Thanks in advance for your time.

Peter Veentjer

ยังไม่อ่าน,
12 ก.ย. 2565 08:42:5312/9/65
ถึง mechanica...@googlegroups.com
If T1 would run first, the content of the ConcurrentHashMap is (1,true), and therefore there is only 1 value.

So it will print 'true' and not 'true,true' because T2 has not run yet.

--
You received this message because you are subscribed to the Google Groups "mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mechanical-symp...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/mechanical-sympathy/0945e8e3-1070-4166-b269-1c4e6c49da3en%40googlegroups.com.

Alper Tekinalp

ยังไม่อ่าน,
12 ก.ย. 2565 09:01:4512/9/65
ถึง mechanica...@googlegroups.com
From util.concurrent:

> Actions in a thread prior to placing an object into any concurrent collection happen-before actions subsequent to the access or removal of that element from the collection in another thread.

So ether one of threads will print (true, true) I guess.

Peter Veentjer

ยังไม่อ่าน,
12 ก.ย. 2565 09:11:1312/9/65
ถึง mechanica...@googlegroups.com
I think this example is better:

class Foo{
  int x;
}

Thread1:
   Foo foo = new Foo();
   foo.x = 10;                                           (1)
   concurrentMap.put("1", foo);             (2)

Thread2:
    Foo foo = concurrentMap.get("1");   (3)
    if(foo!=null) print(foo.x);                   (4)

There is a happens-before edge between (1) and (2) due to program-order rule. And also between (3) and (4) there is a happens-before edge due to program-order rule.

And if thread2 sees the non null value, then there is a happens-before edge between (2) and (3) due to either the volatile variable rule or monitor lock rule (often this is called memory consistency effects on e.g. queues)

Since the happens-before relation is transitive, there is a happens-before edge between (1) and (4).

r r

ยังไม่อ่าน,
12 ก.ย. 2565 10:50:5612/9/65
ถึง mechanica...@googlegroups.com
Thanks, for your response. I know that output "true" is possible. My question is: Is it guaranteed by JMM that one of T1, T2 will print "true, true"? 

Avi Zohary

ยังไม่อ่าน,
12 ก.ย. 2565 11:44:3112/9/65
ถึง mechanical-sympathy
I think the issue here is more the ConcurrentHashMap that doesn't promise you'll get both entries when calling c.values() in either one of the threads.

r r

ยังไม่อ่าน,
12 ก.ย. 2565 14:46:3812/9/65
ถึง mechanical-sympathy
> I think the issue here is more the ConcurrentHashMap that doesn't promise you'll get both entries when calling c.values() in either one of the threads.

What do you mean?

Vijayant Dhankhar

ยังไม่อ่าน,
12 ก.ย. 2565 15:26:0112/9/65
ถึง mechanical-sympathy
For your original formulation for the problem.. 

> Is it guaranteed by JMM that any thread (T1 or T2) prints true, true?
> To put it in another way, is it guaranteed that T1 or T2 observes both c.put?

Yes, one of the thread will print true, true as there is a happens-before between the two writes to concurrent hash map (even if they are possibly on the keys that map to different bins)

r r

ยังไม่อ่าน,
12 ก.ย. 2565 15:36:0912/9/65
ถึง mechanical-sympathy
@Vijayant Dhankhar, thanks. 

How do you know it, I mean:
* that there is a happens-before between writes ()
* c.values is ensured to see two writes?

Avi Zohary

ยังไม่อ่าน,
12 ก.ย. 2565 18:03:1212/9/65
ถึง mechanical-sympathy
I'm not absolutely sure about this, but it is possible that each thread will be running on different cores, and their respective put operations will fall into different bins in the CHM. Looking at the CHM, there is no guarantee that reads will return data from different threads' concurrent writes. 
However, the returned Collection from the call to values() returns a collection that is backed by the CHM data. So there is a second race condition in the reads - it's possible that each thread will see only the data that it wrote on its own, and it's possible that any one of them will see both writes. 
ตอบทุกคน
ตอบกลับผู้สร้าง
ส่งต่อ
ข้อความใหม่ 0 รายการ