- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Inner objects inside a class are not singletons
Fri, 2008-12-19, 12:09
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
Fri, 2008-12-19, 12:37
#2
Re: Inner objects inside a class are not singletons
Singleton as defined by most people mean "single instance per application" (what the heck is "application" anyways?).
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
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
On Fri, Dec 19, 2008 at 12:06 PM, Sebastien Bocq <sebastien.bocq@gmail.com> wrote:
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
Fri, 2008-12-19, 12:37
#3
Re: Inner objects inside a class are not singletons
Yes. But Sebastien is right about multithreading problem.
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
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
On Fri, Dec 19, 2008 at 12:24 PM, Simon Holm Thøgersen <odie@cs.aau.dk> wrote:
fre, 19 12 2008 kl. 12:06 +0100, skrev Sebastien Bocq:
> Hi,Each instance of InnerObjectTest get their own object. It is related to
>
> 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.
>
path dependent types in Scala.
So you see exactly what I describe above, right?
> --- 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$".
Simon Holm Thøgersen
> 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.
Fri, 2008-12-19, 12:47
#4
Re: Inner objects inside a class are not singletons
But you might be right about multithreading problem...
I think it should be synchronized, but I guess simple solution could be very costly?
Szymon
I think it should be synchronized, but I guess simple solution could be very costly?
Szymon
On Fri, Dec 19, 2008 at 12:15 PM, Szymon Jachim <sjachim@gmail.com> wrote:
Singleton as defined by most people mean "single instance per application" (what the heck is "application" anyways?).
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!"
SzymonOn Fri, Dec 19, 2008 at 12:06 PM, Sebastien Bocq <sebastien.bocq@gmail.com> wrote: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
Fri, 2008-12-19, 12:57
#5
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
Fri, 2008-12-19, 13:17
#6
Re: Inner objects inside a class are not singletons
Yeah, object access/initialization code should be the same as lazy val access/initialization code. This looks like a bug to me. I'd suggest you file it.
--
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
On Fri, Dec 19, 2008 at 3:29 AM, Szymon Jachim <sjachim@gmail.com> wrote:
Yes. But Sebastien is right about multithreading problem.
It two threads reference an object at once (and both try to initialize it) it might happen that one callsbefore the other does
> 1: getfield #18; //Field unique$module:LInnerObjectTest
and effectively there will be two instances of the object.
> 16: putfield #18; //Field unique$module:LInnerObjectTest
But don't have much experiance on JVM programming so I might be talking non-sense.
SzymonOn Fri, Dec 19, 2008 at 12:24 PM, Simon Holm Thøgersen <odie@cs.aau.dk> wrote:
fre, 19 12 2008 kl. 12:06 +0100, skrev Sebastien Bocq:
> Hi,Each instance of InnerObjectTest get their own object. It is related to
>
> 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.
>
path dependent types in Scala.
So you see exactly what I describe above, right?
> --- 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$".
Simon Holm Thøgersen
> 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.
--
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
Fri, 2008-12-19, 15:07
#7
Re: Inner objects inside a class are not singletons
Done.
https://lampsvn.epfl.ch/trac/scala/ticket/1591
https://lampsvn.epfl.ch/trac/scala/ticket/1591
2008/12/19 David Pollak <feeder.of.the.bears@gmail.com>
Yeah, object access/initialization code should be the same as lazy val access/initialization code. This looks like a bug to me. I'd suggest you file it.--On Fri, Dec 19, 2008 at 3:29 AM, Szymon Jachim <sjachim@gmail.com> wrote:
Yes. But Sebastien is right about multithreading problem.
It two threads reference an object at once (and both try to initialize it) it might happen that one callsbefore the other does
> 1: getfield #18; //Field unique$module:LInnerObjectTest
and effectively there will be two instances of the object.
> 16: putfield #18; //Field unique$module:LInnerObjectTest
But don't have much experiance on JVM programming so I might be talking non-sense.
SzymonOn Fri, Dec 19, 2008 at 12:24 PM, Simon Holm Thøgersen <odie@cs.aau.dk> wrote:
fre, 19 12 2008 kl. 12:06 +0100, skrev Sebastien Bocq:
> Hi,Each instance of InnerObjectTest get their own object. It is related to
>
> 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.
>
path dependent types in Scala.
So you see exactly what I describe above, right?
> --- 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$".
Simon Holm Thøgersen
> 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.
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
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.