12 Replies Latest reply: Feb 10, 2009 4:53 PM by 807588 RSS

    HashMap thread safe for multi-thread read-only operations?

    807588
      If I have a HashMap (initialized and loaded) via static initialization of the class and I never write to it or modify it again, it is thread-safe for multiple read-only threads? In other words, I don't need to use synchronization or a synchronized map, do I?

      I believe I should be OK since the JVM handles the static initialization at class loading time, which is guaranteed to only happen once, so the mapping should be created in a thread-safe manner. From then on, if I only read from it I should be OK, right?

      Thanks!!
        • 1. Re: HashMap thread safe for multi-thread read-only operations?
          791266
          den2681 wrote:
          If I have a HashMap (initialized and loaded) via static initialization of the class and I never write to it or modify it again, it is thread-safe for multiple read-only threads? In other words, I don't need to use synchronization or a synchronized map, do I?

          I believe I should be OK since the JVM handles the static initialization at class loading time, which is guaranteed to only happen once, so the mapping should be created in a thread-safe manner. From then on, if I only read from it I should be OK, right?
          It will probably work, but I think that you theoretically might run into problems.
          • 2. Re: HashMap thread safe for multi-thread read-only operations?
            807588
            You can enforce the read-only nature with an [unmodifiable Map|http://java.sun.com/javase/6/docs/api/java/util/Collections.html#unmodifiableMap(java.util.Map)].

            ~
            • 3. Re: HashMap thread safe for multi-thread read-only operations?
              807588
              Thanks, I am wrapping my map via Collections.unmodifiableMap, but forget to mention it!
              • 4. Re: HashMap thread safe for multi-thread read-only operations?
                807588
                kajbj wrote:
                den2681 wrote:
                If I have a HashMap (initialized and loaded) via static initialization of the class and I never write to it or modify it again, it is thread-safe for multiple read-only threads? In other words, I don't need to use synchronization or a synchronized map, do I?

                I believe I should be OK since the JVM handles the static initialization at class loading time, which is guaranteed to only happen once, so the mapping should be created in a thread-safe manner. From then on, if I only read from it I should be OK, right?
                It will probably work, but I think that you theoretically might run into problems.
                What would you recommend then, for the least performance impact? ConcurrentHashMap?
                • 5. Re: HashMap thread safe for multi-thread read-only operations?
                  791266
                  (The theoretical problem is that you can execute on e.g. a multi core machine, and I don't think that anything says that the changes to the map must be written to main memory)
                  • 6. Re: HashMap thread safe for multi-thread read-only operations?
                    807588
                    kajbj wrote:
                    (The theoretical problem is that you can execute on e.g. a multi core machine, and I don't think that anything says that the changes to the map must be written to main memory)
                    So if I mark my "private static" initialization function as also being "synchronized", would that enforce that the map setup is flushed to main memory? I believe this happens when you exit a synchronized block/method...

                    Or could I simply mark my HashMap as being volatile?
                    • 7. Re: HashMap thread safe for multi-thread read-only operations?
                      807588
                      kajbj wrote:
                      (The theoretical problem is that you can execute on e.g. a multi core machine, and I don't think that anything says that the changes to the map must be written to main memory)
                      Since the Map is being initialized and loaded in a static block, that will happen during class loading, so all those "changes" will be there in the multi-core case.

                      I think the OP is saying that after class loading, the map is not modified, so the map will be thread-safe for reading operations. If you're paranoid, you could use ConcurrentHashMap.
                      • 8. Re: HashMap thread safe for multi-thread read-only operations?
                        807588
                        den2681 wrote:
                        Or could I simply mark my HashMap as being volatile?
                        That would gain you nothing since that only applies to the map reference, which I assume isn't changing.
                        • 9. Re: HashMap thread safe for multi-thread read-only operations?
                          807588
                          I'd probably just do
                              //
                              public static Map<String,String> MAP = Collections.unmodifiableMap(new HashMap<String,String>() {{
                                  put("key1","value1");
                                  put("key2","value2");
                                  put("key3","value3");
                              }});
                          Not that it matters how you do it; it will go in some class initialiser regardless and class loading is thread safe.
                          • 10. Re: HashMap thread safe for multi-thread read-only operations?
                            791266
                            DrLaszloJamf wrote:
                            kajbj wrote:
                            (The theoretical problem is that you can execute on e.g. a multi core machine, and I don't think that anything says that the changes to the map must be written to main memory)
                            Since the Map is being initialized and loaded in a static block, that will happen during class loading, so all those "changes" will be there in the multi-core case.

                            I think the OP is saying that after class loading, the map is not modified, so the map will be thread-safe for reading operations. If you're paranoid, you could use ConcurrentHashMap.
                            Ah, ok.
                            • 11. Re: HashMap thread safe for multi-thread read-only operations?
                              EJP
                              HashMap thread safe for multi-thread read-only operations?
                              Err, practically anything I can think of is safe for multi-thread read-only operations ...
                              • 12. Re: HashMap thread safe for multi-thread read-only operations?
                                807588
                                ejp wrote:
                                HashMap thread safe for multi-thread read-only operations?
                                Err, practically anything I can think of is safe for multi-thread read-only operations ...
                                Unless it's something that doesn't change the observable state but still mutates data between the sheets. For example, ArrayList's trimToSize .

                                Or a method causes some lazy operation to be triggered:
                                class A {
                                    B b;
                                
                                    C getC() {
                                        if (b == null) {
                                            b = new B();
                                        }
                                        return b.getC();
                                    }
                                }