1 2 Previous Next 15 Replies Latest reply: Aug 31, 2011 2:03 AM by 796440 RSS

    when to load or store data to main memory in thread?

    qiao
      hi,everybody.
      recently,i'm studying java concurrent.

      I learnt something about java memory model, it said that thread will cache some data in it's working space.

      My question is that thread will cache what kind of data ,and when to load or store them,is there something difference using synchronized or not.

      thanks.
        • 1. Re: when to load or store data to main memory in thread?
          qiao
          my question comes from the program below,i think in readDelay will show old date ;
          package cn.org.supersoft.thread;
          
          import java.util.Date;
          
          public class MonitorTest {
          private Date a = new Date();
          public void readDelay(){
          synchronized (a) {
          try {
          Thread.sleep(3000);
          System.out.println(a);
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          }
          }
          public void change(){
          try {
          System.out.println("change in"+a);
          Thread.sleep(1000);
          a = new Date();
          System.out.println("change out"+a);
          Thread.sleep(6000);
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          }
          public static void main(String[] args) {
          final MonitorTest mt =new MonitorTest();
          Thread t1 = new Thread(new Runnable() {
          public void run() {
          mt.readDelay();
          }
          });
          Thread t2 = new Thread(new Runnable() {
          public void run() {
          mt.change();
          }
          });
          t1.start();t2.start();
          }
          }
           
          Edited by: user5449747 on 2011-8-30 下午8:06
          • 2. Re: when to load or store data to main memory in thread?
            796440
            user5449747 wrote:
            My question is that thread will cache what kind of data ,and when to load or store them,is there something difference using synchronized or not.
            It can cache whatever it wants. What to cache and when to sync with main memory is left largely up to the implementation. All that is required (roughly) is the following:

            1) Every read and write of a volatile variable will go against the main copy. No caching.

            2) After entering a sync block, the first read of every shared variable will come from main memory, not from the thread's local copy.

            3) Before exiting a sync block, every shared variable that has been changed will have its new value written out to main memory.

            4) When executing a constructor, every final instance variable in that class will have its value written to main memory before the reference to the new object is visible to the caller.

            The real rules are much more complex and detailed than that, but these are their primary effects. If you want details, read the Memory Model chapter of the JLS: http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.4
            • 3. Re: when to load or store data to main memory in thread?
              796440
              user5449747 wrote:
              my question comes from the program below
              When posting code, use code tags so it will be readable: https://forums.oracle.com/forums/ann.jspa?annID=1429
              i think in readDelay will show old date ;
              Either one is legal. Running it multiple times may give the old value sometimes and the new value other times. The new value seems more likely though.
              • 4. Re: when to load or store data to main memory in thread?
                qiao
                thank you.After reading your reply,i still have some question

                1).in the method change() ,when to store the variable "a" ,store immediately?

                2).I change the method readDelay() like below,
                     public void readDelay(){
                          synchronized (a) {
                               try {
                                    System.out.println(a);//1
                                    Thread.sleep(3000);
                                    System.out.println(a);//2
                               } catch (InterruptedException e) {
                                    e.printStackTrace();
                               }
                          }
                     }
                 
                why variable "a" show in the place 2 is different from place 1?

                Edited by: user5449747 on 2011-8-30 下午8:06
                • 5. Re: when to load or store data to main memory in thread?
                  796440
                  user5449747 wrote:
                  thank you.After reading your reply,i still have some question

                  1).in the method change() ,when to store the variable "a" ,store immediately?
                  By "store" I assume you mean storing it to main memory, as opposed to just a local (cache) copy.

                  There's no syncing in change(), and variable "a" is not declared volatile, so the JVM is free to do whatever it wants. It might write directly to main memory, or it might write to the thread's local copy first and to main memory later, or it might just write it only to the local copy and never write to main memory at all.

                  2).I change the method readDelay() like below,
                       public void readDelay(){
                            synchronized (a) {
                                 try {
                                      System.out.println(a);//1
                                      Thread.sleep(3000);
                                      System.out.println(a);//2
                                 } catch (InterruptedException e) {
                                      e.printStackTrace();
                                 }
                            }
                       }
                  why variable "a" show in the place 2 is different from place 1?
                  Obviously because the other thread wrote a value between our read at 1 and our read at 2.
                  • 6. Re: when to load or store data to main memory in thread?
                    qiao
                    jverd wrote:
                    Obviously because the other thread wrote a value between our read at 1 and our read at 2.
                    but how to explain the cache in this method?You mean that maybe from main memory or local copy ( Except for first read)?
                    • 7. Re: when to load or store data to main memory in thread?
                      796440
                      user5449747 wrote:
                      jverd wrote:
                      Obviously because the other thread wrote a value between our read at 1 and our read at 2.
                      but how to explain the cache in this method?You mean that maybe from main memory or local copy ( Except for first read)?
                      I don't know what you're having trouble understanding. I've already stated this twice: Without volatile or syncing, we can't predict whether threads' local copies or the master copy will be read and written; it's not defined. It can go however the JVM, OS, and hardware choose to do it. With syncing, as we have here the first read of "a" must come from main mem, but subsequent reads can come from the thread's cache. They can also come from main mem. We don't know and we don't care. It's not part of the spec.

                      In this particular case, thread T1 sees one value, and then sees a different value even though T1 didn't write, we can conclude, in this specific case, on this specific JVM, in this specific OS on this specific hardware, for this specific run of the program, that T2 wrote that second value to main memory and T1's second read must have come from main memory; otherwise, T1 wouldn't have been able to see T2's write.

                      However, we cannot predict what will happen next time we run this program, or if we run it on a different JVM or different hardware. T2's write could go to its cache. T1's second read could come from its cache.

                      You need to understand that threads are never required to use local copies of values. Any read or write can go against main mem. If syncing or volatile is involved, then reads and writes are required to go against main mem in the manner I described above. If there's no syncing or volatile, then we don't know and don't care if it's main mem or a cache.

                      Edited by: jverd on Aug 30, 2011 10:09 PM
                      • 8. Re: when to load or store data to main memory in thread?
                        qiao
                        jverd wrote:
                        I don't know what you're having trouble understanding. I've already stated this twice: Without volatile or syncing, we can't predict whether threads' local copies or the master copy will be read and written; it's not defined. It can go however the JVM, OS, and hardware choose to do it. With syncing, as we have here the first read of "a" must come from main mem, but subsequent reads can come from the thread's cache. They can also come from main mem. We don't know and we don't care. It's not part of the spec.

                        In this particular case, thread T1 sees one value, and then sees a different value even though T1 didn't write, we can conclude, in this specific case, on this specific JVM, in this specific OS on this specific hardware, for this specific run of the program, that T2 wrote that second value to main memory and T1's second read must have come from main memory; otherwise, T1 wouldn't have been able to see T2's write.

                        However, we cannot predict what will happen next time we run this program, or if we run it on a different JVM or different hardware. T2's write could go to its cache. T1's second read could come from its cache.

                        You need to understand that threads are never required to use local copies of values. Any read or write can go against main mem. If syncing or volatile is involved, then reads and writes are required to go against main mem in the manner I described above. If there's no syncing or volatile, then we don't know and don't care if it's main mem or a cache.

                        Edited by: jverd on Aug 30, 2011 10:09 PM
                        all above said is based on this ?it have a sync block!
                        public void readDelay(){
                                  synchronized (a) {
                                       try {
                                            System.out.println(a);//1
                                            Thread.sleep(3000);
                                            System.out.println(a);//2
                                       } catch (InterruptedException e) {
                                            e.printStackTrace();
                                       }
                                  }
                        }
                        • 9. Re: when to load or store data to main memory in thread?
                          EJP
                          It is synchronized on the initial value of 'a'. There is nothing there to prevent 'a' from changing.
                          • 10. Re: when to load or store data to main memory in thread?
                            796440
                            user5449747 wrote:
                            all above said is based on this ?
                            On that and on the spec.
                            it have a sync block!
                            I know. And as I've already told you, twice, all that sync block does for this code regarding local copy vs. main mem is that it forces the first read of "a" to come from main mem. That's all. The second read can come from main mem or from a local copy. In this case, because we see the other thread's write, we know it must have come from main mem, but it is not required to.

                            As I've already stated.

                            So what part are you having trouble understanding? If you just want to shout, "It has a sync block!" instead of asking a coherent question, then I can't help you.
                            • 11. Re: when to load or store data to main memory in thread?
                              qiao
                              ok,thank you very much.my question has been resolved.
                              • 12. Re: when to load or store data to main memory in thread?
                                796440
                                Cool. Glad you got it!
                                • 13. Re: when to load or store data to main memory in thread?
                                  802316
                                  jverd wrote:
                                  It can cache whatever it wants. What to cache and when to sync with main memory is left largely up to the implementation. All that is required (roughly) is the following:
                                  I am quibbling but.... AFAIK Java doesn't control the cache in any way (this is very hard to do well even in C)
                                  The CPU determines when data is passed between L1 caches and between L1, L2, L3 and main memory.
                                  1) Every read and write of a volatile variable will go against the main copy. No caching.
                                  This implies a performance penalty you won't actually see. This is because the caches "talk" to each other and pass values between them. A volatile field can be just as fast as a non-volatile field to access for this reason. Volatile ensures all caches see a consistent copy of the value.
                                  2) After entering a sync block, the first read of every shared variable will come from main memory, not from the thread's local copy.
                                  Again, the caches ensure the data is consistent between them. How they actually do this is hardware dependant.
                                  3) Before exiting a sync block, every shared variable that has been changed will have its new value written out to main memory.
                                  Some CPU don't send out the data they just flag that the address region is dirty and if another cache tries to access it, the data is sent.
                                  4) When executing a constructor, every final instance variable in that class will have its value written to main memory before the reference to the new object is visible to the caller.
                                  It is only guaranteed for final fields. It is almost always the case for non-final fields as well which means your software can pass all the tests and even work fine for years, but upgrading the hardware or changing the JVM version can reveal there has been a bug all along. Its best to understand the guarantees and use them appropriately.
                                  • 14. Re: when to load or store data to main memory in thread?
                                    EJP
                                    Moderator: deleted 3 copies of this reply. Being trigger happy JV's reply went with it, sorry.
                                    1 2 Previous Next