10 Replies Latest reply: May 5, 2010 5:28 PM by 807580 RSS

    Do we need synchronization in case of only reading the shared object

    807580
      My Guess would be no for below cases.
      1) When the shared object is final
      2)When the shared object is immutable

      Rest of the cases, I believe we need synchronization.

      Pls share your thoughts.
        • 1. Re: Do we need synchronization in case of only reading the shared object
          807580
          Soph wrote:
          My Guess would be no for below cases.
          1) When the shared object is final
          There's no such thing as a final object
          2)When the shared object is immutable
          Correct. No need to synchronize access to that. You may wish to synchronize instantiation of that object, though.
          • 2. Re: Do we need synchronization in case of only reading the shared object
            807580
            georgemc wrote:
            1) When the shared object is final
            There's no such thing as a final object
            final Map<String, Integer> ascMap=new LinkedHashMap<String, Integer>();

            In this case, ascMap is final variable right? But this can be modified by threads using put().
            So , we need to synchronize reading in this case.

            >
            2)When the shared object is immutable
            Correct. No need to synchronize access to that. You may wish to synchronize instantiation of that object, though.
            Yes
            • 3. Re: Do we need synchronization in case of only reading the shared object
              807580
              Soph wrote:
              georgemc wrote:
              1) When the shared object is final
              There's no such thing as a final object
              final Map<String, Integer> ascMap=new LinkedHashMap<String, Integer>();

              In this case, ascMap is final variable right?
              But the variable isn't the object
              But this can be modified by threads using put().
              So , we need to synchronize reading in this case.
              Well, "need" is a subjective concept.
              • 4. Re: Do we need synchronization in case of only reading the shared object
                796440
                georgemc wrote:
                Soph wrote:
                georgemc wrote:
                1) When the shared object is final
                There's no such thing as a final object
                final Map<String, Integer> ascMap=new LinkedHashMap<String, Integer>();

                In this case, ascMap is final variable right?
                But the variable isn't the object
                To expand upon that a bit: The concept of "final" does not apply to objects. It applies to variables, and remember, variables hold primitives or references, not objects. Declaring a variable final simply means that the variable's value cannot change after initialization. It has no effect whatsoever on the object the variable points to.

                >
                But this can be modified by threads using put().
                So , we need to synchronize reading in this case.
                Well, "need" is a subjective concept.
                But yes, if you have multiple threads running concurrently, and at least one of them is doing a "put" or "remove" or anything else that alters the state of the Map, then you'll have to synchronize all access to the map.
                • 5. Re: Do we need synchronization in case of only reading the shared object
                  807580
                  jverd wrote:
                  georgemc wrote:
                  Soph wrote:
                  georgemc wrote:
                  1) When the shared object is final
                  There's no such thing as a final object
                  final Map<String, Integer> ascMap=new LinkedHashMap<String, Integer>();

                  In this case, ascMap is final variable right?
                  But the variable isn't the object
                  To expand upon that a bit: The concept of "final" does not apply to objects. It applies to variables, and remember, variables hold primitives or references, not objects. Declaring a variable final simply means that the variable's value cannot change after initialization. It has no effect whatsoever on the object the variable points to.
                  Cheers Jeff

                  >>
                  But this can be modified by threads using put().
                  So , we need to synchronize reading in this case.
                  Well, "need" is a subjective concept.
                  But yes, if you have multiple threads running concurrently, and at least one of them is doing a "put" or "remove" or anything else that alters the state of the Map, then you'll have to synchronize all access to the map.
                  And just to expand a bit on that, this only matters if any of those other threads also accesses, or may access, that map as well.
                  • 6. Re: Do we need synchronization in case of only reading the shared object
                    807580
                    Thanks for your replies.
                    Apart from Immutable objects, are there any other situations where it is safe to allow multiple threads for reading purpose concurrent/without synchronization ?
                    • 7. Re: Do we need synchronization in case of only reading the shared object
                      796440
                      georgemc wrote:
                      jverd wrote:
                      But yes, if you have multiple threads running concurrently, and at least one of them is doing a "put" or "remove" or anything else that alters the state of the Map, then you'll have to synchronize all access to the map.
                      And just to expand a bit on that, this only matters if any of those other threads also accesses, or may access, that map as well.
                      By "access" you mean read, or just any use of the map at all?

                      If you mean any use of the map at all--read or write--then yeah, my bad for not being clear. That is, if there are 50 threads running, but only one of them is doing anything at all with the map, then syncing the map access isn't necessary.

                      However, if by "access" you meant "read", then yes and no. That is, the statement "it only matters if at least one thread is reading and at least one thread is writing", while technically true, can be misleading.

                      For instance, you may ask, "I have multiple threads doing puts, but they're *only* doing puts, the gets and iterations and other reading method calls come after those threads have completed all the puts, does this mean I don't need to synchronize?" The thinking being, there's no writing going on concurrently with any reading, since all the "write" calls (put) end before any of the "read" calls (get) begin.

                      However, while you may view put() strictly as a writing call because of its public semantics, under the hood, it has to do some reading to figure out if the value is already present, possibly adjust the internal hash buckets, etc. So therefore, even if you think you're only writing, if multiple threads are touching the map and at least one of them is writing, then all access to the map must be synchronized. This rule applies in general, not just to maps.

                      For that matter, now that I think about it, just as "write" operations may need to to a read as part of their job, so might "read" operations need to do a write. For instance, an object may cache its hashCode, and may lazily compute it. If two threads call hashCode() concurrently, even though it externally looks like a pure "read" operation, there could be writes and a race condition. Or look at GregorianCalendar, which lazily updates its internal state when the various "read" methods are called.

                      I guess a better rule would be: If multiple threads are concurrently reading/writing/touching/accessing the same object in any way whatsoever, then in the general case, you have to synchronize all access to that object. (I say "in the general case" because depending on what you know about the object's implementation or what its docs say, you may be able to loosen those rules on a case-by-case basis.)

                      Okay, I'm done ranting. You may go about your business. :-)
                      • 8. Re: Do we need synchronization in case of only reading the shared object
                        807580
                        However, while you may view put() strictly as a writing call because of its public semantics, under the hood, it has to do some reading to figure out if the value is already present, possibly adjust the internal hash buckets, etc. So therefore, even if you think you're only writing, if multiple threads are touching the map and at least one of them is writing, then all access to the map must be synchronized. This rule applies in general, not just to maps.

                        For that matter, now that I think about it, just as "write" operations may need to to a read as part of their job, so might "read" operations need to do a write. For instance, an object may cache its hashCode, and may lazily compute it. If two threads call hashCode() concurrently, even though it externally looks like a pure "read" operation, there could be writes and a race condition. Or look at GregorianCalendar, which lazily updates its internal state when the various "read" methods are called.

                        I guess a better rule would be: If multiple threads are concurrently reading/writing/touching/accessing the same object in any way whatsoever, then in the general case, you have to synchronize all access to that object. (I say "in the general case" because depending on what you know about the object's implementation or what its docs say, you may be able to loosen those rules on a case-by-case basis.)
                        Concurrent hash map offers concurrent reading and writing(at bucket level). How are the above scenarios handled in concurrent hash map?
                        • 9. Re: Do we need synchronization in case of only reading the shared object
                          YoungWinston
                          Soph wrote:
                          Concurrent hash map offers concurrent reading and writing(at bucket level). How are the above scenarios handled in concurrent hash map?
                          I think, unless you read otherwise, you should take it that operations are individually synchronized. Which is to say that if you decide to add 500 items to a CHM, all threads will see the map in a consistent state, but they may all see it in a different state.

                          Winston
                          • 10. Re: Do we need synchronization in case of only reading the shared object
                            807580
                            jverd wrote:
                            georgemc wrote:
                            jverd wrote:
                            But yes, if you have multiple threads running concurrently, and at least one of them is doing a "put" or "remove" or anything else that alters the state of the Map, then you'll have to synchronize all access to the map.
                            And just to expand a bit on that, this only matters if any of those other threads also accesses, or may access, that map as well.
                            By "access" you mean read, or just any use of the map at all?
                            Anything at all. Something the OP said made me think they felt the need to synchronise simply because their app is multi-threaded