-2

how

lets say i have this class

@ImmutableWannabe
public class ConfigurationHolder {
  @ImmutableButHowToMakeSureNoTwoThreadsOverrideOneEachOtherWhenReplacingReference
  private Map<System, Configuration> mySysConfig  = ImmutableMap.builder<>getSomeConfigurations....build();
  ConfigurationHolder(copy constructor) {
     mySysConfig = ImmutableMap.builder().of(inputSysConfig);
  }
}

Now lets say one of the systems configuration has updated and i need to update this map of however I need to do it in a thread safe way. which means if two threads try to update the same configuration of same system data should be consistent and they should not override one each other.

How did immutability help me here? As far as i can see i still need to do locking if yes how to do it properly?

so my general question is: isn't it the case that any immutableObject which can change over system time will cause us to need to lock the code that will need to change its ImmutableObjectHolder? I don't get it...

can someone please give a proper example of an ImmutableMap + Holder for that Map + proper "client" code that knows to update this ImmutableMapHolder with updates to the internal Map?

thanks

Jas
  • 14,493
  • 27
  • 97
  • 148
  • You cannot update the immutable map, but you can point your holder to a different one. This way, no thread will see an inconsistent map (they will only the either the old one, or the new one, but not a weird mix). – Thilo Jan 29 '13 at 06:34
  • yeah sure but when i point it to another map don't i need to make sure that two threads that were aware of two different maps because they read them at two different points in time are now changing the pointers to two different ones and this will cause errors? if that's the case I still need to worry about locks also with immutableObjects is that right? – Jas Jan 29 '13 at 06:35
  • if you have two threads that want to update the holder, then yes, they need to lock (optimistically or pessimistically). You probably want an AtomicReference for that. But threads that only read don't need any locking. – Thilo Jan 29 '13 at 06:37
  • If you're updating the `ImmutableMap`, you really really shouldn't be marking `ConfigurationHolder` as itself immutable. – Louis Wasserman Jan 29 '13 at 06:47
  • yeah, so at the end of the row there will always be a mutable object to hold all these immutable ones right? (In case i need to replace the immutable ones, any escape here to avoid any kind of such mutable holders?). – Jas Jan 29 '13 at 06:49

1 Answers1

1

Assuming your map is some instance variable, the simplest way it to make it volatile. Alternatively, make a getter and setter for it and make them synchronized. i.e., use standard techniques. And note that this won't help if the client tries to be clever and cache the value in a local variable. (I've bitten myself with this bug a couple of times.)

I guess as an alternative you could setup some MyImmutableChanged event/listener.

And, you are correct, immutability doesn't solve every threading problem.

user949300
  • 15,364
  • 7
  • 35
  • 66
  • thanks alot can you please just elaborate when would i use volatile in such cases and when AtomicReference in such cases? – Jas Jan 29 '13 at 06:52
  • 1
    See [this SO post] (http://stackoverflow.com/questions/281132/java-volatile-reference-vs-atomicreference). Short answer is that either works. I tend to use volatile cause I never think of AtomicReference. :-) – user949300 Jan 29 '13 at 06:55