ensuring only one instance of an object exists?

D

Daisy

I have a Swing applet (possibly similar to yesterday's Rich Clients
topic) which pops up some classes that extend JFrame. I'd like to
ensure that only one instance of a particular JFrame exists.

My brute force approach is to create a static boolean variable for each
class in the Applet's initializing class. Then I test their boolean
before instantiating each class. If the variable is already set, don't
instantiate a new class. Is there a more elegant test for whether a
particular class is already instantiated?

Thanks
 
A

Andy

Hi,


search for "singleton pattern".
It is a architecture pattern for your problem.
The main parts are:
- make constructor private (-> you can't create instances of the class
from outside)
- add a (private) static member variable to the class, which stores the
reference to the only existing object
- add a (public) 'getInstance()' methode which returns the only existing
object

Greetings,
Andy
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Daisy said:
I have a Swing applet (possibly similar to yesterday's Rich Clients
topic) which pops up some classes that extend JFrame. I'd like to
ensure that only one instance of a particular JFrame exists.

My brute force approach is to create a static boolean variable for each
class in the Applet's initializing class. Then I test their boolean
before instantiating each class. If the variable is already set, don't
instantiate a new class. Is there a more elegant test for whether a
particular class is already instantiated?

Sounds as if you need a singleton.

But I have never seen a singleton class that extends JFrame.

Arne
 
J

jcsnippets.atspace.com

I have a Swing applet (possibly similar to yesterday's Rich Clients
topic) which pops up some classes that extend JFrame. I'd like to
ensure that only one instance of a particular JFrame exists.

My brute force approach is to create a static boolean variable for each
class in the Applet's initializing class. Then I test their boolean
before instantiating each class. If the variable is already set, don't
instantiate a new class. Is there a more elegant test for whether a
particular class is already instantiated?

Thanks

Have a look at the Singleton pattern - I wrote a little article about it,
including examples on how to use it.
http://jcsnippets.atspace.com/java/patterns/what-is-a-singleton.html

Best regards,

JayCee
 
J

jagonzal

jcsnippets.atspace.com said:
Have a look at the Singleton pattern - I wrote a little article about it,
including examples on how to use it.
http://jcsnippets.atspace.com/java/patterns/what-is-a-singleton.html

Hi,

I read your article, and there's this line that jumps out at me:

"Both examples given above do NOT have an explicit constructor - which
means they both get the default private constructor."

This is wrong, if you do not define an explicit constructor, you
inherit the default PUBLIC constructor.

This test code (using the example singleton classes in your article):

public class Test {
public static void main(String args[]){
StaticSingleton s = new StaticSingleton();
SynchronizedSingleton ss = new SynchronizedSingleton();
System.out.println(StaticSingleton.getInstance().equals(s));
System.out.println(SynchronizedSingleton.getInstance().equals(ss));
}
}

Outputs:

% java Test
false
false

Which means I have two distinct instances of the singleton class. When
defining a singleton, you MUST define the private constuctor(s) -
unless you don't mind people being able to create new instances outside
your static one ;)
 
C

Chris Uppal

This is wrong, if you do not define an explicit constructor, you
inherit the default PUBLIC constructor.

....if the class itself is public.

If not then the compiler-supplied constructor attempts to match the
accessibility of the class (which calls for some very odd jiggery-pokery if the
class is private -- as it can be if it is nested).

Even a singleton class might not be public (the single instance's class might
be a subclass of a public class, or implement a public interface) -- although I
admit that's not the most common situation ;-)

-- chris
 
J

jagonzal

Chris said:
...if the class itself is public.

If not then the compiler-supplied constructor attempts to match the
accessibility of the class (which calls for some very odd jiggery-pokery if the
class is private -- as it can be if it is nested).

Thanks for the comment - I didn't know that :)
 
J

jcsnippets.atspace.com

(e-mail address removed) wrote in

jcsnippets.atspace.com said:
Have a look at the Singleton pattern - I wrote a little article about
it, including examples on how to use it.
http://jcsnippets.atspace.com/java/patterns/what-is-a-singleton.html

Hi,

I read your article, and there's this line that jumps out at me:

"Both examples given above do NOT have an explicit constructor - which
means they both get the default private constructor."

This is wrong, if you do not define an explicit constructor, you
inherit the default PUBLIC constructor.

This test code (using the example singleton classes in your article):

public class Test {
public static void main(String args[]){
StaticSingleton s = new StaticSingleton();
SynchronizedSingleton ss = new SynchronizedSingleton();
System.out.println(StaticSingleton.getInstance().equals(s));
System.out.println(SynchronizedSingleton.getInstance().equals(ss));
}
}

Outputs:

% java Test
false
false

Which means I have two distinct instances of the singleton class. When
defining a singleton, you MUST define the private constuctor(s) -
unless you don't mind people being able to create new instances
outside your static one ;)

First of all, forgive my late reply.

Second - Ouch... You're right - I'm going to change this as soon as
possible.

Thank you for pointing this out!

Best regards,

JayCee
 
S

su_dang

jcsnippets.atspace.com said:
(e-mail address removed) wrote in
jcsnippets.atspace.com said:
Have a look at the Singleton pattern - I wrote a little article about
it, including examples on how to use it.
http://jcsnippets.atspace.com/java/patterns/what-is-a-singleton.html

Hi,

I read your article, and there's this line that jumps out at me:

"Both examples given above do NOT have an explicit constructor - which
means they both get the default private constructor."

This is wrong, if you do not define an explicit constructor, you
inherit the default PUBLIC constructor.

This test code (using the example singleton classes in your article):

public class Test {
public static void main(String args[]){
StaticSingleton s = new StaticSingleton();
SynchronizedSingleton ss = new SynchronizedSingleton();
System.out.println(StaticSingleton.getInstance().equals(s));
System.out.println(SynchronizedSingleton.getInstance().equals(ss));
}
}

Outputs:

% java Test
false
false

Which means I have two distinct instances of the singleton class. When
defining a singleton, you MUST define the private constuctor(s) -
unless you don't mind people being able to create new instances
outside your static one ;)

First of all, forgive my late reply.

Second - Ouch... You're right - I'm going to change this as soon as
possible.

Thank you for pointing this out!

Best regards,

JayCee

The singleton pattern only works per class loader. If your JVM uses
multiple class loaders, or if you have multiple JVMs, the singleton
pattern won't work.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

The singleton pattern only works per class loader. If your JVM uses
multiple class loaders, or if you have multiple JVMs, the singleton
pattern won't work.

If the JVM has multiple classloaders *and* more than one classloader
has the class in its classpath *and* none of the classloaders are
parent, then it is possible to get multipl instances.

Whether multiple instances is working or not working in theese
scenarios are depends on the specifics. If it is a Tomcat web hotel
with shared JVM, then not sharing singleton instances with other
customers should be called working.

Arne
 
J

jcsnippets.atspace.com

(e-mail address removed) wrote in

The singleton pattern only works per class loader. If your JVM uses
multiple class loaders, or if you have multiple JVMs, the singleton
pattern won't work.

Just curious: is there a way to solve this?

Best regards,

JayCee
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

jcsnippets.atspace.com said:
(e-mail address removed) wrote in



Just curious: is there a way to solve this?

In general no.

In EJB context it can be an alternative to tell the
container to only create one instance of an EJB.

Arne
 
C

Chris Uppal

jcsnippets.atspace.com said:
Just curious: is there a way to solve this?

Not without a fairly elaborate superstructure (which you would have to build)
to allow classloaders to negotiate between themselves.

But really there's no point. If you have a classfile aaa.bbb.C loaded by two
separate classloaders then you don't have "the same class loaded twice", you
have two completely independent classes (which happen to be similar in some
ways -- such as their names). Instances of one are /not/ substitutable for
instances of the other. So if that/those classes are playing singleton games,
then the only appropriate behaviour is for the two different classes to have
two different singleton instances -- which is exactly what you do get.

There are cases where your really want to restrict this further (e.g. if the
singleton instance represents some single physical entity -- such as the
computer's mouse). In such cases you will have to ensure that the shared class
is loaded by a single shared classloader, visible to -- and a parent of -- all
the other classloaders. But then, if you have an architecture with such
"genuine" singletons, then they'll obviously have to be part of the shared
sub-set of the application anyway.

-- chris
 
M

Mike Schilling

Chris Uppal said:
Not without a fairly elaborate superstructure (which you would have to
build)
to allow classloaders to negotiate between themselves.

How about by ensuring that your class is in the bootstrap classpath? There
are classloaders that cheat by not checking the parent first, but I'd hope
that they all check the system classloader first.
 
C

Chris Uppal

Mike said:
How about by ensuring that your class is in the bootstrap classpath?
There are classloaders that cheat by not checking the parent first, but
I'd hope that they all check the system classloader first.

That's pretty much what my post said. Someone had claimed (correctly but
misleadingly) that "The singleton pattern only works per class loader" -- I was
attempting to fill in the gaps by pointing out that in nearly every case,
either you would naturally use a shared classloader (so there's no problem), or
that you don't /want/ a shared singleton.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top