0

If I have this:

public class Foo {
    public int bar;

    public Foo(int bar) {
        this.bar = bar;

        synchronized (Foo.class) {
            Foo.instance = this;
            Foo.class.notify();
        }
    }

    public static Foo instance;

    public static Foo instance() {
        synchronized (Foo.class) {
            if (Foo.instance == null) {
                Foo.class.wait();
            }

            return instance;
        }
    }
}

And in another class I have this, at any and all unspecified points in the future, assuming I have NOT yet altered the value of Bar by any means:

int baz = Foo.instance().bar;

Is there any possibility at all of having Foo . Instance ( ) . Bar return uninitialized gibberish? My thought is that, since I have assured that nothing will ever try to access Bar before the Instance variable is set, that the JIT compiler cannot optimize away anything and must read from main memory, but is this true? Is it possible for it to somehow get compiled so that it instead pulls 0 (which was the value of Bar before it was set to the new value in the constructor).

isnot2bad
  • 24,105
  • 2
  • 29
  • 50
JAKJ
  • 289
  • 1
  • 4
  • 14
  • 1
    If you intend to share your code with any other than yourself (and you're currently doing it), then don't ignore the naming and spacing conventions of Java: that makes your code unreadable. – JB Nizet Nov 19 '13 at 20:47
  • It looks like you're trying to do a singleton https://en.wikipedia.org/wiki/Singleton_pattern – Taylor Nov 19 '13 at 20:50
  • My question is about the non-synchronized instance variable that is set before the singleton is stored, not the singleton itself. I want to know if the value of the instance variable set in the initializer is guaranteed to be correct when another thread accesses it after the singleton has been synchronized. – JAKJ Nov 19 '13 at 20:52
  • Have a look at: [What is an efficient way to implement a singleton pattern in Java?](http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java?lq=1) – Andrey Chaschev Nov 19 '13 at 20:56
  • Again, I'm not talking about the singleton: I'm talking about the instance field `Bar`. – JAKJ Nov 19 '13 at 21:06
  • Doesn't work. If e.g two threads call Foo.instance() before the instance has been set, only one of them will be notified. The other will sleep forever! – isnot2bad Nov 19 '13 at 21:13
  • Not if one thread calls `new Foo()` before calling `Foo.instance()`. But anyway, my question is settled now. – JAKJ Nov 19 '13 at 21:21
  • 1
    If you can ensure that new Foo is created before a thread calls Foo.instance, then you don't need wait and notify at all! Just skip them! – isnot2bad Nov 19 '13 at 21:23

1 Answers1

1

There are many ways to implement singleton - this one is the most odd I have ever seen. If it's not singleton - note that two instances of this class cannot be used concurrently.

If you use only one instance of this class it will not return any gibber if only variable Bar is declared as volatile in this case. Otherwise strange things, such as 0-returns can occur.

Maciej Dobrowolski
  • 11,561
  • 5
  • 45
  • 67
  • So it is possible for `Bar` to return as zero instead of its value set in the constructor, even though the instance is never accessed externally until the construction is complete, unless `Bar` is set to be volatile or final? – JAKJ Nov 19 '13 at 21:04
  • @JAKJ No. Even if a second instance of Foo is created and hence set as new instance, it is published safely and so no visibility problems will occure. Nevertheless very strange code that suffers from other problems (see my question comment). Whatever you want to achieve - don't do it that way, it's probably wrong! – isnot2bad Nov 19 '13 at 21:19
  • @JAKJ the problem is that `Boo` field is public what can make stale-data to be visible in other threads. As constructor will safely publish this value - threads which are using `Boo` not necessarly bother it. The same to `Foo instance` field. – Maciej Dobrowolski Nov 19 '13 at 21:23