Singleton: Difference between revisions
Thread safe Ada version |
added java |
||
Line 327: | Line 327: | ||
Mary got (2)Rosetta |
Mary got (2)Rosetta |
||
Peter got (3)Code</pre> |
Peter got (3)Code</pre> |
||
=={{header|Java}}== |
|||
===Thread-safe=== |
|||
<pre> |
|||
class Singleton |
|||
{ |
|||
private static Singleton myInstance; |
|||
public static synchronized Singleton getInstance() |
|||
{ |
|||
if (myInstance == null) |
|||
myInstance = new Singleton(); |
|||
return myInstance; |
|||
} |
|||
protected Singleton() |
|||
{ |
|||
// Constructor code goes here. |
|||
} |
|||
// Any other methods |
|||
} |
|||
</pre> |
|||
===Non-Thread-Safe=== |
|||
<pre> |
|||
class Singleton |
|||
{ |
|||
private static Singleton myInstance; |
|||
public static Singleton getInstance() |
|||
{ |
|||
if (myInstance == null) |
|||
myInstance = new Singleton(); |
|||
return myInstance; |
|||
} |
|||
protected Singleton() |
|||
{ |
|||
// Constructor code goes here. |
|||
} |
|||
// Any other methods |
|||
} |
|||
</pre> |
Revision as of 23:47, 2 March 2008
You are encouraged to solve this task according to the task description, using any language you may know.
A Global Singleton is a class of which only one instance exists within a program. Any attempt to use non-static members of the class involves performing operations on this one instance.
Ada
Non Thread Safe
<ada> package Global_Singleton is
type Singleton is limited private; procedure Set_Data(Item : out Singleton; Value : Integer); function Get_Data(Item : Singleton) return Integer; function Create return Singleton;
private
type Instance_Type is record -- Define instance data elements Data : Integer := 0; end record; type Singleton is access all Instance_Type; Instance : aliased Instance_Type;
end Global_Singleton;</ada>
<ada>package body Global_Singleton is
-------------- -- Set_Data -- --------------
procedure Set_Data (Item : out Singleton; Value : Integer) is begin if Item = null then Item := Create; end if; Item.Data := Value; end Set_Data;
-------------- -- Get_Data -- --------------
function Get_Data (Item : Singleton) return Integer is begin return Item.Data; end Get_Data;
------------ -- Create -- ------------
function Create return Singleton is begin return Instance'access; end Create;
end Global_Singleton;</ada>
Thread Safe
<ada>package Protected_Singleton is
type Singleton is limited private; procedure Set_Data(Item : out Singleton; Value : Integer); function Get_Data(Item : Singleton) return Integer; function Create return Singleton;
private
protected type Instance_Type is procedure Set(Value : Integer); function Get return Integer; private Data : Integer := 0; end Instance_Type; type Singleton is access all Instance_Type; Instance : aliased Instance_Type;
end Protected_Singleton;</ada>
<ada>package body Protected_Singleton is
-------------- -- Set_Data -- --------------
procedure Set_Data (Item : out Singleton; Value : Integer) is begin if Item = null then Item := Create; end if; Instance.Set(Value); end Set_Data;
-------------- -- Get_Data -- --------------
function Get_Data (Item : Singleton) return Integer is begin return Instance.Get; end Get_Data;
------------ -- Create -- ------------
function Create return Singleton is begin return Instance'access; end Create;
------------------- -- Instance_Type -- -------------------
protected body Instance_Type is
--------- -- Set -- ---------
procedure Set (Value : Integer) is begin Data := Value; end Set;
--------- -- Get -- ---------
function Get return Integer is begin return Data; end Get;
end Instance_Type;
end Protected_Singleton;</ada>
C++
Thread-safe
Operating System: Microsoft Windows NT/XP/Vista
class Singleton { public: static Singleton* Instance() { // We need to ensure that we don't accidentally create two Singletons HANDLE hMutex = CreateMutex(NULL, FALSE, "MySingletonMutex"); WaitForSingleObject(hMutex, INFINITE); // Create the instance of the class. // Since it's a static variable, if the class has already been created, // It won't be created again. static Singleton myInstance; // Release our mutex so that other application threads can use this function ReleaseMutex( hMutex ); // Free the handle CloseHandle( hMutex ); // Return a pointer to our mutex instance. return &myInstance; } // Any other public methods protected: Singleton() { // Constructor code goes here. } ~Singleton() { // Destructor code goes here. } // And any other protected methods. }
Non-Thread-Safe
This version doesn't require any operating-system or platform-specific features, but it is not safe in a multi-threaded environment.
class Singleton { public: static Singleton* Instance() { // Since it's a static variable, if the class has already been created, // It won't be created again. static Singleton myInstance; // Return a pointer to our mutex instance. return &myInstance; } // Any other public methods protected: Singleton() { // Constructor code goes here. } ~Singleton() { // Destructor code goes here. } // And any other protected methods. }
E
Since E uses closure-style objects rather than classes, a singleton is simply an object which is defined at the top level of the program, not inside any method. There are no thread-safety issues since the singleton, like every other object, belongs to some particular vat (but can be remotely invoked from other vats).
def aSingleton { # ... }
Objective-C
Non-Thread-Safe
(Using Cocoa's NSObject as a base class)
// SomeSingleton.h @interface SomeSingleton : NSObject { // any instance variables } + (SomeSingleton*)sharedInstance; @end
// SomeSingleton.m @implementation SomeSingleton + (SomeSingleton*) sharedInstance { static sharedInstance = nil; if(!sharedInstance) { sharedInstance = [[SomeSingleton alloc] init]; } return sharedInstance; } @end
D
<d>module singleton ; import std.stdio ; import std.thread ; import std.random ; import std.c.time ;
class Dealer {
static Dealer me ; static Dealer Instance() { synchronized { // this part of code can only be executed by one thread a time if(me is null) { // some delay so that other threads has chance to call this synchronized code for(int i = 0 ; i < 6 ; i++) { writefln("...calling Dealer... ") ; msleep(rand() & 2047) ; } me = new Dealer ; } } return me ; } static string[] str = ["(1)Enjoy", "(2)Rosetta", "(3)Code"] ; int state ; private this() { writefln(">>Dealer is called to come in!") ; state = str.length - 1 ; } Dealer nextState() { synchronized { state = (state + 1) % str.length ; } return this ; } string toString() { return str[state] ; }
} class Coder : Thread {
string name_ ; Coder hasName(string name) { name_ = name ; return this ; } override int run() { msleep(rand() & 2047) ; writefln(">>%s come in.", name_) ; Dealer single = Dealer.Instance ; for(int i = 0 ; i < 3 ; i++) { writefln("%9s got %-s", name_, single.nextState) ; msleep(rand() & 1023) ; } return 0 ; }
} void main() {
Coder x = new Coder ; Coder y = new Coder ; Coder z = new Coder ; x.hasName("Peter").start() ; y.hasName("Paul").start() ; z.hasName("Mary").start() ;
x.wait ; y.wait ; z.wait ;
}</d> Sample Output:
>>Mary come in. ...calling Dealer... >>Peter come in. ...calling Dealer... >>Paul come in. ...calling Dealer... ...calling Dealer... ...calling Dealer... ...calling Dealer... >>Dealer is called to come in! Paul got (1)Enjoy Peter got (2)Rosetta Mary got (3)Code Paul got (1)Enjoy Mary got (2)Rosetta Paul got (3)Code Peter got (1)Enjoy Mary got (2)Rosetta Peter got (3)Code
Java
Thread-safe
class Singleton { private static Singleton myInstance; public static synchronized Singleton getInstance() { if (myInstance == null) myInstance = new Singleton(); return myInstance; } protected Singleton() { // Constructor code goes here. } // Any other methods }
Non-Thread-Safe
class Singleton { private static Singleton myInstance; public static Singleton getInstance() { if (myInstance == null) myInstance = new Singleton(); return myInstance; } protected Singleton() { // Constructor code goes here. } // Any other methods }