Does immutability guarantee thread safety?

前端 未结 2 881
南旧
南旧 2021-01-24 17:50

Well, consider the immutable class Immutable as given below:

public final class Immutable
{
    final int x;
    final int y;
    public Immutable(i         


        
相关标签:
2条回答
  • 2021-01-24 18:30

    So, Thread B could see the write to objas occurring before the writes to the fields of the Immutable. Hence Thread B could thus see a partially constructed Immutable that may well be in an invalid state and whose state may unexpectedly change later.

    In Java 1.4, this was true. In Java 5.0 and above, final fields are thread safe after construction.

    0 讨论(0)
  • 2021-01-24 18:33

    What you're describing here are two different things. First, Immutable is thread safe if the operations are being done to an instance of it.

    Thread safety is, in part, ensuring that memory isn't accidentally overwritten by another thread. Insofar as using Immutable, you can never overwrite any data contained in an instance of it, so you can feel confident that, in a concurrent environment, an Immutable object will be the same when you constructed it to when the threads are manipulating it.

    What you've got right there is a broken implementation of double-checked locking.

    You're right in that Thread A and Thread B may trample the instance before it's set, thus making the whole immutability of the object Immutable completely moot.

    I believe that the approach to fix this would be to use the volatile keyword for your obj field, so that Java (> 1.5) will respect the intended use of the singleton, and disallow threads to overwrite the contents of obj.

    Now, having read a bit closer, it seems to be a bit wonky that you'd have an immutable singleton that required two pieces of static data for it to exist. It seems more like this would be suited towards a factory instead.

    public class Sharable {
        private Sharable() {
        }
    
        public static Immutable getImmutableInstance(int a, int b) {
            return new Immutable(a, b);
        }
    }
    

    Every instance of Immutable you get will truly be immutable - creating a new Immutable has no impact on the others, and using an instance of Immutable has no impact on any others as well.

    0 讨论(0)
提交回复
热议问题