8 Replies Latest reply: Jun 16, 2011 2:09 PM by 796440 RSS

    volatile variableflush value to  main memory?

    866541
      i was going through volatile reading material through some websites including http://download.oracle.com.
      Some of them mentioned below points

      Point1 :-volatile role comes in to picture when when you are working on shared variables
      with multiple threads.

      fulshPoint 2:-This allows threads that access shared variables to keep private
      working copies of the variables.These working copies needs to be flushed to
      main memory only at prescribed synchronization points



      Question on Point1:- when we are referring shared variable here .there can be two cases :-

      A)It can be static variable .then it will be a shared variable across multiple threads

      B)It can be instance variable when same instance is shared across multiple threads

      Question on Point2:- Here main memory means either method area memory or heap memory?Does that mean when we update
      either static variable or instance variable , intialy thread keep them on some local regiter then at some logical
      point jvm flush them to method area(in case of static) or heap area(in case of instance variable )


      if above points are true then below example given on site http://www.javabeat.net/tips/169-volatile-keyword-in-java.html
      does not seems to be true as the variable i.e testValue is not a shared variable for threads Thread1 and Thread2 ?


      package javabeat.samples;

      class ExampleThread extends Thread {
           private volatile int testValue;
           public ExampleThread(String str){
                super(str);
           }
           public void run() {
                for (int i = 0; i < 3; i++) {
                     try {
                          System.out.println(getName() + " : "+i);
                          if (getName().equals("Thread 1 "))
                          {
                               testValue = 10;
                          }
                          if (getName().equals("Thread 2 "))
                          {
                               System.out.println( "Test Value : " + testValue);
                          }                    
                          Thread.sleep(1000);
                     } catch (InterruptedException exception) {
                          exception.printStackTrace();
                     }
                }
           }
      }
      public class VolatileExample {
           public static void main(String args[]) {
                new ExampleThread("Thread 1 ").start();
                new ExampleThread("Thread 2 ").start();
           }
      }
        • 1. Re: volatile variableflush value to  main memory?
          796440
          JavaFunda wrote:
          i was going through volatile reading material through some websites including http://download.oracle.com.
          Some of them mentioned below points

          Point1 :-volatile role comes in to picture when when you are working on shared variables
          with multiple threads.

          fulshPoint 2:-This allows threads that access shared variables to keep private
          working copies of the variables.These working copies needs to be flushed to
          main memory only at prescribed synchronization points
          No. When a variable is declared volatile, that means that threads are not allowed to keep local copies of that variable. Every read and write of a volatile variable must go against the single copy in main memory.
          Question on Point1:- when we are referring shared variable here .there can be two cases :-

          A)It can be static variable .then it will be a shared variable across multiple threads

          B)It can be instance variable when same instance is shared across multiple threads
          I don't see a question here. A "shared variable" is a variable that is accessed by multiple threads. It can be a class variable (static member variable) or an instance variable (non-static member variable). Local variables are never shared.
          Question on Point2:- Here main memory means either method area memory or heap memory
          Heap.
          ?Does that mean when we update
          either static variable or instance variable , intialy thread keep them on some local regiter then at some logical
          point jvm flush them to method area(in case of static) or heap area(in case of instance variable )
          The thread can keep a local copy (if the variable is not volatile). It doesn't have to.
          if above points are true then below example given on site http://www.javabeat.net/tips/169-volatile-keyword-in-java.html
          does not seems to be true as the variable i.e testValue is not a shared variable for threads Thread1 and Thread2 ?


          package javabeat.samples;

          class ExampleThread extends Thread {
               private volatile int testValue;
          That variable is not shared in this example, because each thread has its own instance of ExampleThread. If it were static, it would be shared.
          • 2. Re: volatile variableflush value to  main memory?
            796440
            In the future, when posting code, use code tags: http://forums.oracle.com/forums/ann.jspa?annID=1429
            • 3. Re: volatile variableflush value to  main memory?
              802316
              No. When a variable is declared volatile, that means that threads are not allowed to keep local copies of that variable. Every read and write of a volatile variable must go against the single copy in main memory.
              This will not mean it will go back to main memory or the same memory on every access. The caches must ensure you will never see an old copy. I don't think defines how the CPU(s) should do this.
              A)It can be static variable .then it will be a shared variable across multiple threads
              You can have local variables, instances fields and static fields. Local variables are local to a thread, though they can refer to the same object.
              B)It can be instance variable when same instance is shared across multiple threads
              Instances dont have variables (variables are only on the stack), instances have fields.

              Usually this is just a quibble and it doesn't matter if you are not being technically correct, but when you are talking about thread safety, comparing a field and a variable makes a big difference.
              Question on Point2:- Here main memory means either method area memory or heap memory
              main memory is all the RAM which is not in the CPU cache or only on disk. You should never need to worry about the consistency of JVM internal memory like that used for methods.
              volatile only gives you have control over heap memory.
              ?Does that mean when we update
              either static variable or instance variable , intialy thread keep them on some local regiter then at some logical
              point jvm flush them to method area(in case of static) or heap area(in case of instance variable )
              You cannot update the memory used for methods, only the JVM does this. You can update heap memory which contain static and non-static fields.
              if above points are true then below example given on site http://www.javabeat.net/tips/169-volatile-keyword-in-java.html
              does not seems to be true as the variable i.e testValue is not a shared variable for threads Thread1 and Thread2 ?
              Its still called a shared variable even if its not thread safe.
              Making a field volatile is not the only way to provide thread safety, so it can be shared, thread safe and not volatile.
              I would say using synchronized blocks is the most common way to ensure shared fields are thread safe.
              class ExampleThread extends Thread {
                   private volatile int testValue;
              That variable is not shared in this example, because each thread has its own instance of ExampleThread. If it were static, it would be shared.
              .. and you have more than one ExampleThread.
              • 4. Re: volatile variableflush value to  main memory?
                866541
                Question on Point2:- Here main memory means either method area memory or heap memory
                Heap.
                Hi Jverd can't the main memory be method area memory in case of static variable? Can't thread can keep local copy

                of static variable just like it can keep instance variable?

                Does that mean when we update
                ther static variable or instance variable , intialy thread keep them on some local regiter then at some logical
                int jvm flush them to method area(in case of static) or heap area(in case of instance variable )
                he thread can keep a local copy (if the variable is not volatile). It doesn't have to.
                But ultimately that local copy has to be flushed to heap?
                • 5. Re: volatile variableflush value to  main memory?
                  796440
                  JavaFunda wrote:
                  Question on Point2:- Here main memory means either method area memory or heap memory
                  Heap.
                  Hi Jverd can't the main memory be method area memory in case of static variable? Can't thread can keep local copy

                  of static variable just like it can keep instance variable?
                  I never said otherwise.

                  And don't write in all bold. It's very annoying.

                  >
                  >
                  Does that mean when we update
                  ther static variable or instance variable , intialy thread keep them on some local regiter then at some logical
                  int jvm flush them to method area(in case of static) or heap area(in case of instance variable )
                  he thread can keep a local copy (if the variable is not volatile). It doesn't have to.
                  But ultimately that local copy has to be flushed to heap?
                  If you use synchronization, yes. If not, it never has to be flushed to the main copy. But that doesn't matter, because if you're not using synchronization, then it's because you don't care if other threads see it. (Or because there are no other threads.)
                  • 6. Re: volatile variableflush value to  main memory?
                    796440
                    Peter Lawrey wrote:
                    No. When a variable is declared volatile, that means that threads are not allowed to keep local copies of that variable. Every read and write of a volatile variable must go against the single copy in main memory.
                    This will not mean it will go back to main memory or the same memory on every access. The caches must ensure you will never see an old copy. I don't think defines how the CPU(s) should do this.
                    I think you're mistaken here, but the JLS and JVM Spec pages are dead links.

                    I guess it doesn't matter though. The main point, as far as the OP is concerned, is that it must behave as if every access goes against a single local copy.

                    >
                    A)It can be static variable .then it will be a shared variable across multiple threads
                    You can have local variables, instances fields and static fields. Local variables are local to a thread, though they can refer to the same object.
                    B)It can be instance variable when same instance is shared across multiple threads
                    Instances dont have variables (variables are only on the stack), instances have fields.

                    Usually this is just a quibble and it doesn't matter if you are not being technically correct, but when you are talking about thread safety, comparing a field and a variable makes a big difference.
                    I don't think the JLS makes the distinction between variables and fields, but again, I can't confirm it right now. {noformat}:-){noformat}
                    Its still called a shared variable even if its not thread safe.
                    I think it has to actually be shared by multiple threads though to earn that moniker. No variable in the OP's code was.
                    Making a field volatile is not the only way to provide thread safety, so it can be shared, thread safe and not volatile.
                    I would say using synchronized blocks is the most common way to ensure shared fields are thread safe.
                    class ExampleThread extends Thread {
                         private volatile int testValue;
                    That variable is not shared in this example, because each thread has its own instance of ExampleThread. If it were static, it would be shared.
                    .. and you have more than one ExampleThread.
                    Eh? Not sure what you're saying here.
                    • 7. Re: volatile variableflush value to  main memory?
                      866541
                      i was trying to notice the case where the value of primitive type change by one thread does not get reflected in another thread, without declaring the variable as volatile.
                      but could not reproduce that scenario.
                      Because i tried a programme in which two threads are started. i tied to change the instance variable(without modifier volatile) in one thread, it was reflected in thread two probably in fraction of seconds.

                      if we dont declare the instance variable as volatile, i know thread will keep the local copy for some time.But Ultimately they are written to main memory. At what point of time they are wriitten to main memory? is there any specification for that or its jvm decision?

                      Edited by: JavaFunda on Jun 16, 2011 11:29 AM
                      • 8. Re: volatile variableflush value to  main memory?
                        796440
                        JavaFunda wrote:
                        i was trying to notice the case where the value of primitive type change by one thread does not get reflected in another thread, without declaring the variable as volatile.
                        but could not reproduce that scenario.
                        You can't guarantee that is will happen. It's possible, but it depends on a lot of implementation-dependent, hardware-dependent, OS-dependent, code-dependent, and context-dependent factors.

                        And even if the write does hang out in the thread's local copy for millions of CPU cycles, there's no way to be sure that your test code will catch it. It's less than the blink of an eye to you and me, but the CPU can do a lot of work with the wrong value in a millisecond. And the very act of trying to view the value may ultimately trigger a cache flush.
                        if we dont declare the instance variable as volatile, i know thread will keep the local copy for some time
                        No, you don't. You know that it can. There's a big difference between can and will.
                        But Ultimately they are written to main memory. At what point of time they are wriitten to main memory? is there any specification for that or its jvm decision?
                        The spec only says under what conditions things must be written to or read from main memory. For anything not explicitly specified as such, the value can go to or come from a local copy or main memory, and we cannot predict or control which.

                        (Or, if Peter's earlier comments are accurate, the spec dictates when the code must behave as if the values were written to main memory. As programmers striving for correct code, there's no difference to us.)