seand
seand

Reputation: 5296

Java, multithreaded class, configuration, avoiding synchronization

Let's say I have a class that requires configuration, dependency injection etc.

public class MyClass {
   private String someConfig;
   private SomeMutableClass anotherConfig;


   MyClass() {
     // impractical to set everything in ctor
     // otherwise I'd declare someConfig final and 
     // not worry about MT safety.
   }

   void setConfig(cfg) {
     this.someConfig = cfg;
   }
   void anotherConfig(cfg) {
     this.anotherConfig = cfg;
   }

   ...

   // below is code that uses the config set before, possibly by
   // multiple threads.

}

This is a contrived example, but what if I can't easily do all the config in the ctor? Let's say the config is done early in execution and doesn't change. Strictly speaking due to the memory model I'd have to synchronize all references to someConfig. Can this requirement be relaxed in practice?

Upvotes: 2

Views: 272

Answers (3)

Eugene Retunsky
Eugene Retunsky

Reputation: 13139

If this class is initialized via Spring, then this definition is sufficient. No need to synchronize access or make fields volatile.

Practically speaking, if the initialization has been performed, for example, inside a synchronization block, then all local thread data has been flushed to the main memory and will be accessible to all threads for reading.

Upvotes: 1

jefflunt
jefflunt

Reputation: 33954

I think biziciop's straightforward answer if perfectly fine to your question. My answer speaks more to the philosophical reason for choosing one way over the other, so take it for what it's worth.

You might be able to relax requirements that you can prove, through proper testing, never happen in actuality; that is, to model the situation you're worried about in a test. I'm a fan of not over-engineering things to match the best practice, just because it's the best practice.

Then again, if a concurrent access bug comes about due to your lack of planning, either you (or some future programmer, if this is a system that you'll hand off to others) may curse you.

I suppose the question is, why do you want to avoid the requirement? Is it (1) because, in your design, it will never actually happen? Is it (2) to make code clear, which would otherwise be much uglier/harder to read/harder to maintain. Or is it (3) because of a deeper feature of multi-threading and synchronization in general?

If it is only for reason #3 (and I don't know if that applies to you specifically, but I do see a number of programmers who fall into this category), then I'd say it's not a sufficient reason, on its own, to relax the requirement. If it's for one, or both of either #1 or #2, then you might be okay, so long as you're fully aware of the trade off you're making.

Upvotes: 1

biziclop
biziclop

Reputation: 49794

Yes, by declaring the field as volatile.

Upvotes: 2

Related Questions