tag:blogger.com,1999:blog-8405107760807432973.post5825384944681355315..comments2024-01-04T09:55:32.459-08:00Comments on Java Concurrency (&c): Volatile Arrays in JavaJeremy Mansonhttp://www.blogger.com/profile/04241094734813086257noreply@blogger.comBlogger42125tag:blogger.com,1999:blog-8405107760807432973.post-47287844449819636712023-06-15T13:49:20.425-07:002023-06-15T13:49:20.425-07:00Common mistake - there is no volatile write in set...Common mistake - there is no volatile write in set(). There's a volatile read of the array variable, followed by a normal write of 1 to element 0. So, there is no happens-before relationship between the set and the get.<br /><br />If you want arrays whose elements can be read and written atomically, use AtomicXArrays from java.util.concurrent.atomic.<br /><br />HB relationships are often Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-47474542502173130822023-06-13T07:37:47.160-07:002023-06-13T07:37:47.160-07:00volatile int[] array = new int[] {0};
public synch...volatile int[] array = new int[] {0};<br />public synchronized void set() {<br /> array[0] = 1;<br />}<br />public int get() {<br /> return array[0];<br />}<br /><br />Is it possible for the "get" thread to read 0 after the "set" thread has finished? <br />I am trying to understand whether happens before relationship means just a flush to the main memory and reordering Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-58726908963681573342023-06-13T06:30:25.047-07:002023-06-13T06:30:25.047-07:00@anonymous: sure, but how can you tell whether the...@anonymous: sure, but how can you tell whether the <b>arr = arr</b> line has executed? arr will have the same value either way.Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-79990027580480405412023-06-13T05:35:09.117-07:002023-06-13T05:35:09.117-07:00Writer thread:
arr[0] = 1;
arr = arr;
Reader thre...Writer thread:<br />arr[0] = 1;<br />arr = arr;<br /><br />Reader thread:<br />int one = arr[0];<br /><br />Let’s assume that a read always goes after arr = arr; has been executed.<br />arr = arr; happens before (happens before relationship) arr (reading arr reference) from the reader thread. Therefore arr[0] = 1; is also visible from the reader thread and one == 1. Am I right with my reasoning?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-45829360612994746142021-07-12T21:11:44.109-07:002021-07-12T21:11:44.109-07:00@anonymous Because all writes of normal variables ...@anonymous Because all writes of normal variables that happen before a write of a volatile are deemed also to have happened before a read of that value from that volatile, even if it is in another thread. The write and subsequent read create an ordering between the two. Those are the rules, and Java implementations have to find ways to follow them.Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-15219685681470043172021-07-10T08:56:43.172-07:002021-07-10T08:56:43.172-07:00Hi Jeremy,
I understand that Thread2 sees the chan...Hi Jeremy,<br />I understand that Thread2 sees the change of the variable ready. But why does it also see the change of variable answer, although it isnt volatile.Anonymoushttps://www.blogger.com/profile/12247348366125378720noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-61827117513973703932017-08-30T10:27:22.171-07:002017-08-30T10:27:22.171-07:00Nice post, thanks for sharing...Nice post, thanks for sharing...Durantehttps://webfirmframework.github.io/noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-62978954351564999692016-11-18T22:18:30.315-08:002016-11-18T22:18:30.315-08:00No, volatile is volatile. The question is really:...No, volatile is volatile. The question is really: how do you know that you've executed the arr = arr statement and can rely on the volatile guarantee?<br /><br />More to the point, just use AtomicReferenceArray. Not sure why I didn't mention it here.Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-23384339674375822462016-11-11T12:20:15.255-08:002016-11-11T12:20:15.255-08:00Hello Jeremy,
thanks for your post!
So if we use...Hello Jeremy,<br /><br />thanks for your post!<br /><br />So if we use arr = arr, we are guaranteed to see the value that was written, but we might not get the happens-before (and see stale fields of the written object). Is it correct?<br /><br />I'm going through "Concurrency in Practice" and I tried to implement Game of Life using multiple threads and CyclicBarrier. Since each damluarhttps://www.blogger.com/profile/05425803973033514785noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-37615389456673001782016-07-10T16:59:13.151-07:002016-07-10T16:59:13.151-07:00@Sachin: Yes. The absence of a guarantee does not...@Sachin: Yes. The absence of a guarantee does not mean the guarantee of absence.<br /><br />To put it another way, just because you aren't guaranteed to see the updated value, that doesn't mean you won't. It just means you there's no guarantee. You may or may not see it.Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-58036105927545714882016-06-11T21:53:13.055-07:002016-06-11T21:53:13.055-07:00As per the explanation here thread1 should not be ...As per the explanation here thread1 should not be able to read the updated value from boolean[] array but that's not happening here i.e. thread1 reads the updated value and stops. <br /><br />Am I missing something here?<br /><br />class ThreadHolder {<br /> boolean[] flag = new boolean[]{true};<br /> <br /> class Thread1 implements Runnable {<br /> public void run() {<br />Anonymoushttps://www.blogger.com/profile/06536449989922417074noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-22342482459488171302015-10-14T15:32:47.441-07:002015-10-14T15:32:47.441-07:00@~SS~ - This is answered in the post.@~SS~ - This is answered in the post.Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-87444152157289649582015-10-14T05:10:12.642-07:002015-10-14T05:10:12.642-07:00Please tell me; is it volatile object array is pos...Please tell me; is it volatile object array is possible with AtomicReferenceArray or not?~SS~https://www.blogger.com/profile/17157424537949945576noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-7315364178717856362013-09-03T16:11:36.844-07:002013-09-03T16:11:36.844-07:00@anonymous: If the reader sees the updated value, ...@anonymous: If the reader sees the updated value, it has no idea whether the volatile write might have happened (i.e., it can read the value 1 after arr[0] = 1, but before arr = arr). This isn't a big problem with reading a scalar, but it would be a big problem if you were relying on the happens-before relationship for something.Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-31964849201135892012013-09-03T15:15:37.706-07:002013-09-03T15:15:37.706-07:00Hi, you say "In this case, you can't actu...Hi, you say "In this case, you can't actually detect that another thread performed the write, because it is writing the same value to the variable."<br />But what if a new value was written? It would be actually detected.<br />The behaviour is the same using a volatile field.<br /><br />What about this pattern (definitely not a best practice)?<br /><br />volatile int [] arr = ...;<Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-26745987407020629582011-05-13T23:06:41.104-07:002011-05-13T23:06:41.104-07:00That is true, although in practice, you will proba...That is true, although in practice, you will probably see most writes at some point.Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-5337521000283164672011-05-13T16:35:20.597-07:002011-05-13T16:35:20.597-07:00Hi Jeremy,
First off, good article, it was an inf...Hi Jeremy,<br /><br />First off, good article, it was an informative read.<br /><br />I do have one comment though concerning writing a self reference to the array as a method of getting a volatile write.<br /><br />I think that there is a use for such a construct in a situation where an array is being used as a cache. From my understanding of the Java memory model, there is no guarantee that Trevorhttps://www.blogger.com/profile/18364751196541948928noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-85214900400298855332010-09-28T23:21:45.585-07:002010-09-28T23:21:45.585-07:00@Robert - There is a cost associated with using vo...@Robert - There is a cost associated with using volatile fields. It prevents common compiler optimizations, and requires hardware-level memory coherence operations (x86 only requires memory coherence operations for writes, so you see a lot of volatile-based data structures optimized for reads).Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-67007834081107559442010-09-28T14:13:37.960-07:002010-09-28T14:13:37.960-07:00It's beginning to sound like you should never ...It's beginning to sound like you should never NOT use volatile except for immutable classes or local variables.<br /><br />Is there an extra cost with synchronized blocks if the field being accessed is volatile?Robert DiFalcohttps://www.blogger.com/profile/13597446398841679558noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-8419983007583040622010-09-26T13:06:07.427-07:002010-09-26T13:06:07.427-07:00@Robert - that's right. To get publication gu...@Robert - that's right. To get publication guarantees for #name, you need to write a reference to the Person object.Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-68460938426099888222010-09-26T10:02:39.695-07:002010-09-26T10:02:39.695-07:00Don't know if you are still reading this but I...Don't know if you are still reading this but I am assuming that the semantics for object fields are just like the semantics for an array?<br /><br />In other words, if I have a class Persom with a field #name that if #name is not volatile then having Person instances volatile will not garauntee visibility of writes to the name field. Is that right?Robert DiFalcohttps://www.blogger.com/profile/13597446398841679558noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-53340912334102357312010-06-13T11:00:15.048-07:002010-06-13T11:00:15.048-07:00@bruno - array = array would provide a memory barr...@bruno - array = array would provide a memory barrier, but you couldn't guarantee that the reader thread's code would occur after that assignment happened. Usually, if you use a volatile as flags, you have some latch-like behavior:<br /><br />Thread 1:<br />data = o;<br />done = true;<br /><br />Thread 2:<br />if (done) <br /> // use data<br /><br />But you can't check the value of Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-92107188160486601932010-06-10T23:18:17.145-07:002010-06-10T23:18:17.145-07:00Don't bother about my last question. I see now...Don't bother about my last question. I see now, it's more about memory action reordering, than synchronizing actual copies of memory. There are only reads on the array reference itself and "volatile" does not ensure the order of multiple reads without writes.<br /><br />Would it work with an additional "array = array;" in set()?<br /><br />Is there another way to Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-35706768612118128962010-06-06T11:06:32.516-07:002010-06-06T11:06:32.516-07:00volatile int[] array = new int[] {0};
public synch...volatile int[] array = new int[] {0};<br />public synchronized void set() {<br /> array[0] = 1;<br />}<br />public int get() {<br /> return array[0];<br />}<br /><br />Is it possible for the "get" thread to read 0 after the "set" thread has finished? The unlock stores/writes the 1 into main memory (http://java.sun.com/docs/books/jvms/second_edition/html/Threads.doc.html#Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8405107760807432973.post-10494597660767108492010-02-10T09:26:38.815-08:002010-02-10T09:26:38.815-08:00@uthark - the post does make mention of those clas...@uthark - the post does make mention of those classes.Jeremy Mansonhttps://www.blogger.com/profile/04241094734813086257noreply@blogger.com