- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Inner objects inside a class are not singletons
Hi,
I always thoutht the scala 'object' keyword is used to declare a "singleton object" but this thruth doesn't seem to hold for inner objects inside a 'class'. Let me explain using the sample class below and the ouptut generated by javap.
--- Scala ---
abstract class MyType
class InnerObjectTest {
object unique extends MyType
}
--- javap ---
private InnerObjectTest$unique$ unique$module;
...
public final InnerObjectTest$unique$ unique();
Code:
0: aload_0
1: getfield #18; //Field unique$module:LInnerObjectTest$unique$;
4: ifnonnull 19
7: aload_0
8: new #20; //class InnerObjectTest$unique$
11: dup
12: aload_0
13: invokespecial #23; //Method InnerObjectTest$unique$."<init>":(LInnerObjectTest;)V
16: putfield #18; //Field unique$module:LInnerObjectTest$unique$;
19: aload_0
20: getfield #18; //Field unique$module:LInnerObjectTest$unique$;
23: areturn
If I understand correctly the bytecode above, the compiler generates a unique() method to initialize a private field named "unique$module" to a reference to a new instance of type "InnerObjectTest$unique$".
If several threads access the 'unique' "singleton" concurrently, isn't there a small chance that they get different objects? In this is true, then I find this confusing because when obtaining a reference to a singleton instance one doesn't expect to worry about multi-threading issues.
Thanks,
Sebastien
I always thoutht the scala 'object' keyword is used to declare a "singleton object" but this thruth doesn't seem to hold for inner objects inside a 'class'. Let me explain using the sample class below and the ouptut generated by javap.
--- Scala ---
abstract class MyType
class InnerObjectTest {
object unique extends MyType
}
--- javap ---
private InnerObjectTest$unique$ unique$module;
...
public final InnerObjectTest$unique$ unique();
Code:
0: aload_0
1: getfield #18; //Field unique$module:LInnerObjectTest$unique$;
4: ifnonnull 19
7: aload_0
8: new #20; //class InnerObjectTest$unique$
11: dup
12: aload_0
13: invokespecial #23; //Method InnerObjectTest$unique$."<init>":(LInnerObjectTest;)V
16: putfield #18; //Field unique$module:LInnerObjectTest$unique$;
19: aload_0
20: getfield #18; //Field unique$module:LInnerObjectTest$unique$;
23: areturn
If I understand correctly the bytecode above, the compiler generates a unique() method to initialize a private field named "unique$module" to a reference to a new instance of type "InnerObjectTest$unique$".
If several threads access the 'unique' "singleton" concurrently, isn't there a small chance that they get different objects? In this is true, then I find this confusing because when obtaining a reference to a singleton instance one doesn't expect to worry about multi-threading issues.
Thanks,
Sebastien










Re: Inner objects inside a class are not singletons
Scalas definition is single instance per scope in which it's defined.
Gives more flexibility and causes less problems then typical statics.
In my team there's a joke: "it's not a global variable, it's a singleton!"
Szymon
Re: Inner objects inside a class are not singletons
I think it should be synchronized, but I guess simple solution could be very costly?
Szymon
Re: Inner objects inside a class are not singletons
On Fri, Dec 19, 2008 at 12:23:34PM +0100, Szymon Jachim wrote:
> But you might be right about multithreading problem...
> I think it should be synchronized, but I guess simple solution could be very
> costly?
Synchronization is probably not _too_ costly in this context, but it
can be avoided with modern JVMs:
http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl
Lauri
Re: Inner objects inside a class are not singletons
fre, 19 12 2008 kl. 12:06 +0100, skrev Sebastien Bocq:
> Hi,
>
> I always thoutht the scala 'object' keyword is used to declare a
> "singleton object" but this thruth doesn't seem to hold for inner
> objects inside a 'class'. Let me explain using the sample class below
> and the ouptut generated by javap.
>
Each instance of InnerObjectTest get their own object. It is related to
path dependent types in Scala.
Re: Inner objects inside a class are not singletons
It two threads reference an object at once (and both try to initialize it) it might happen that one calls
> 1: getfield #18; //Field unique$module:LInnerObjectTest
before the other does
> 16: putfield #18; //Field unique$module:LInnerObjectTest
and effectively there will be two instances of the object.
But don't have much experiance on JVM programming so I might be talking non-sense.
Szymon
Re: Inner objects inside a class are not singletons
--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Re: Inner objects inside a class are not singletons
https://lampsvn.epfl.ch/trac/scala/ticket/1591