1 2 Previous Next 16 Replies Latest reply on Sep 6, 2007 8:01 PM by 796440

    Static primitives (and Objects) vs Synchronization

    807605
      If in a class delcaration I have
      public static int x = 0;
      public static Foo f = new Foo();
      and multiple threads are accessing x and f, do I need to make sure they use synchronized access or will the class (since they are declared static) take care of synchronization for me?
        • 1. Re: Static primitives (and Objects) vs Synchronization
          791266
          You have to synchronize.
          • 2. Re: Static primitives (and Objects) vs Synchronization
            796440
            It depends.

            Do threads have to see the results of each others' writes to those variables? If so, you must sync or make the variables volatile.

            Are you going to do x++, x--, x+=something, etc., and require a given thread to see the results as if it were single threaded? If so, you must sync. (Merely making volatile won't help.)

            Will you be changing the values of x and f together, in a way that must be seen to be atomic, or doing any other multi-step operation that must be atomic (like changing f's internal state)? If so, you must sync.

            etc.
            • 3. Re: Static primitives (and Objects) vs Synchronization
              796440
              or will the
              class (since they are declared static) take care of
              synchronization for me?
              Where did you get that idea?
              • 4. Re: Static primitives (and Objects) vs Synchronization
                807605
                or will the
                class (since they are declared static) take care
                of
                synchronization for me?
                Where did you get that idea?
                wishful thinking.

                can someone briefly describe the difference between using synchronized access and just declaring things volatile? is volatile only for times when you are only going to read a value? wouldn't you still want to use synchronized access there? i understand when/why to use synchronization, but not how the volatile keyword can help. i'm under the impression if I have a variable X that anytime I read or write to it, it should be done in a synchronized block -- is that wrong?

                the values in my case will definitely be getting changed by different threads, so i will make sure to use synchronized methods/blocks as needed.
                • 5. Re: Static primitives (and Objects) vs Synchronization
                  796440
                  wishful thinking.
                  :-)

                  If that worked, I'd be on a beach in the Bahamas with a bevy of scantily-clad, nubile, youg ladies attending to my every whim, and you'd be on your own for synchronization.


                  can someone briefly describe the difference between
                  using synchronized access and just declaring things
                  volatile?
                  Threads can make local copies of shared variables. So if T1 does x++, and sometime later, T2 does x++, they might both be inc'ing x from 0 to 1, as they can each have their own copy of x.

                  If you declare a variable volatile, then every read and write of that variable must go against the single shared copy, so if T1 does x++ and then later T2 does x++, T1 will inc it from 0 to 1 and T2 from 1 to 2.

                  Syncing goes a little beyond that.

                  An effect similar to that of volatile is that on entering a sync block, the initial read of every shared variable must come from main mem, and on exiting it, every shared variable that was changed must be writtenb back out to shared mem.

                  The main thing that people think of syncing for is obtaining a lock. When I sync on an object, I get that object's lock, and no other thread can get it until I release it, either by calling wait() or by exiting the sync block. So every thread that's trying to sync on the same object has to stop and wait for me.

                  Volatile only deals with individual variables. Syncing allows for more complex exclusive access and atomicity.
                  • 6. Re: Static primitives (and Objects) vs Synchronization
                    791266
                    wishful thinking.
                    :-)

                    If that worked, I'd be on a beach in the Bahamas with
                    a bevy of scantily-clad, nubile, youg ladies
                    attending to my every whim, and you'd be on your own
                    for synchronization.
                    ROFL
                    • 7. Re: Static primitives (and Objects) vs Synchronization
                      807605
                      took a cursory glance at volatile stuff and just a few more questions...

                      1) is it even implemented in java 1.5+? some of the things i've seen say that most JVMs ignore it, didn't know about sun's.

                      2) in your volatile example -- even if x is declared volatile don't you still run the risk of 2 threads screwing up? for instance, if T1 reads (from main memory since it's volatile), then increments, but before it writes back T2 reads (again, from main memory), then T1 writes, then T2 increments & writes -- wouldn't I lose an increment in there?

                      if i'm correct in #2 then again, i still don't see the point in using volatile -- i feel like you should always use synchronized instead since it will get fresh copies of the non-local variables and prevent any other thread from modifying during it's lock.

                      thanks again!
                      • 8. Re: Static primitives (and Objects) vs Synchronization
                        791266
                        took a cursory glance at volatile stuff and just a
                        few more questions...

                        1) is it even implemented in java 1.5+? some of the
                        things i've seen say that most JVMs ignore it, didn't
                        know about sun's.
                        Where did you read that? It's not ignored by the virtual machines.
                        • 9. Re: Static primitives (and Objects) vs Synchronization
                          796365
                          This explains atomic access and volatile, and the surrounding sections cover synchronization.
                          http://java.sun.com/docs/books/tutorial/essential/concurrency/atomic.html
                          • 10. Re: Static primitives (and Objects) vs Synchronization
                            807605
                            took a cursory glance at volatile stuff and just a
                            few more questions...

                            1) is it even implemented in java 1.5+? some of
                            the
                            things i've seen say that most JVMs ignore it,
                            didn't
                            know about sun's.
                            Where did you read that? It's not ignored by the
                            virtual machines.
                            On some old websites I was poking around on -- I'm guessing that info is outdated though.
                            • 11. Re: Static primitives (and Objects) vs Synchronization
                              796440
                              took a cursory glance at volatile stuff and just a
                              few more questions...

                              1) is it even implemented in java 1.5+? some of the
                              things i've seen say that most JVMs ignore it, didn't
                              know about sun's.
                              I believe it is. I remember hearing several years ago (around 1.3) that it was often not implemented correctly because the spec was vague. To be honest, I don't know if I've ever actually used volatile.


                              2) in your volatile example -- even if x is declared
                              volatile don't you still run the risk of 2 threads
                              screwing up? for instance, if T1 reads (from main
                              memory since it's volatile), then increments, but
                              before it writes back T2 reads (again, from main
                              memory), then T1 writes, then T2 increments & writes
                              -- wouldn't I lose an increment in there?
                              If I'm following what you're saying, then yeah, you're on the right track.

                              For instance, x++ is not atomic. It's a 3-step opertaion: Read, Inc, Write. Multiple threads can execute x++ concurrently and interleave those steps, even if x is volatile. It just means that all their reads and writes will be against the main copy.

                              If you're simply doing x=5 however, then that means that as soon as that statement completes, the next thread that reads x will see 5.


                              if i'm correct in #2 then again, i still don't see
                              the point in using volatile -- i feel like you should
                              always use synchronized instead since it will get
                              fresh copies of the non-local variables and prevent
                              any other thread from modifying during it's lock.
                              Volatile could be slightly "lighter weight"--both in terms of source code and execution overhead--if used properly. But like I said, I don't think I've ever used it.
                              • 12. Re: Static primitives (and Objects) vs Synchronization
                                807605
                                thanks guys, great info. i think the reason i have questions about volatile is because every time i look it up it seems kinda pointless (unless some really rare, simple case arises) so i kinda forget about it until it comes up again at which point i have to look into them again.

                                i'm sticking with synchronization for the time being.
                                • 13. Re: Static primitives (and Objects) vs Synchronization
                                  807605
                                  sorry, one last thing I just want to be clear on...
                                  private static int x = 0;
                                  private static Foo f = new Foo();
                                  ....
                                  public syncrhonized bar() {
                                      x++;
                                      f.doSomething();
                                  }
                                  there is no need to declare those 2 variables as volatile, is there? won't the synchronized function take care of reading and writing to main memory for me?

                                  what about in the below case? if i use a block instead of method will it still be sure to read and write all shared variables to & from main memory?
                                  public void bar2() {
                                      synchronized(bar) {
                                          x++;
                                      }
                                  }
                                  • 14. Re: Static primitives (and Objects) vs Synchronization
                                    796440
                                    there is no need to declare those 2 variables as
                                    volatile, is there? won't the synchronized function
                                    take care of reading and writing to main memory for
                                    me?
                                    Correct, as long as all access to them is synchronized.


                                    >
                                    what about in the below case? if i use a block
                                    instead of method will it still be sure to read and
                                    write all shared variables to & from main memory?
                                    public void bar2() {
                                    synchronized(bar) {
                                    x++;
                                    }
                                    }
                                    Yes, HOWEVER, there's something you need to know about locks.

                                    When you sync a non-static method, you're syncing the body on this. When you sync a static method, you're syncing the body on the Class object for that class.
                                    class Foo {
                                      synchronized void bar() { /* body */ }
                                    
                                       // is the same as
                                    
                                      void bar () {
                                        synchronized (this) { /* body */ }
                                      }
                                    
                                    
                                      // AND
                                    
                                    
                                    
                                      static synchronized void bar() { /* body */ }
                                    
                                       // is the same as
                                    
                                      static void bar () {
                                        synchronized (Foo.class) { /* body */ }
                                      }
                                    }
                                    Now, you've got non-static synced methods that access static variables. So if I have two different objects of this class in two different threads and T1 calls bar() on its object and T2 calls bar() on its object, because each non-static bar is syncing on a different "this", there'll be no exclusion, and both threads can execute their bar() methods concurrently.

                                    So you need to do one of the following:

                                    * Make x and f non-static. Whether this makes sense depends on the semantics of those variables, and shouldn't be done just for syncing purposes.

                                    * Make bar() static. Again, depends on the semantics of this method, and should not be done just for syncing.

                                    * Have bar() explicitly sync on an object that can be shared by all instances of this class, for instance, ThisClass.class.
                                    1 2 Previous Next