Singleton: Difference between revisions

From Rosetta Code
Content added Content deleted
m ((D) header reorder & double checked lock)
Line 207: Line 207:
</pre>
</pre>


=={{header|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 [http://www.erights.org/elib/concurrency/vat.html vat] (but can be remotely invoked from other vats).

def aSingleton {
# ...
}

=={{header|Objective-C}}==
===Non-Thread-Safe===

(Using Cocoa's NSObject as a base class)
<pre>
// SomeSingleton.h
@interface SomeSingleton : NSObject
{
// any instance variables
}

+ (SomeSingleton*)sharedInstance;

@end
</pre>

<pre>
// SomeSingleton.m
@implementation SomeSingleton

+ (SomeSingleton*) sharedInstance
{
static sharedInstance = nil;
if(!sharedInstance) {
sharedInstance = [[SomeSingleton alloc] init];
}
return sharedInstance;
}

@end
</pre>
=={{header|D}}==
=={{header|D}}==
<d>module singleton ;
<d>module singleton ;
Line 254: Line 215:


class Dealer {
class Dealer {
static Dealer me ;
private static Dealer me ;
static Dealer Instance() {
static Dealer Instance() {
writefln(" Calling Dealer... ") ;
synchronized { // this part of code can only be executed by one thread a time
if(me is null) {
if(me is null) // Double Checked Lock
// some delay so that other threads has chance to call this synchronized code
synchronized // this part of code can only be executed by one thread a time
for(int i = 0 ; i < 6 ; i++) {
if(me is null)
writefln("...calling Dealer... ") ;
me = new Dealer ;
msleep(rand() & 2047) ;
}
me = new Dealer ;
}
}
return me ;
return me ;
}
}
static string[] str = ["(1)Enjoy", "(2)Rosetta", "(3)Code"] ;
private static string[] str = ["(1)Enjoy", "(2)Rosetta", "(3)Code"] ;
int state ;
private int state ;
private this() {
private this() {
for(int i = 0 ; i < 3 ; i++) {
writefln("...calling Dealer... ") ;
msleep(rand() & 2047) ;
}
writefln(">>Dealer is called to come in!") ;
writefln(">>Dealer is called to come in!") ;
state = str.length - 1 ;
state = str.length - 1 ;
}
}
Dealer nextState() {
Dealer nextState() {
synchronized {
synchronized(this) // accessed to Object _this_ is locked ... is it necessary ???
state = (state + 1) % str.length ;
state = (state + 1) % str.length ;
}
return this ;
return this ;
}
}
string toString() { return str[state] ; }
string toString() { return str[state] ; }
}
}

class Coder : Thread {
class Coder : Thread {
string name_ ;
private string name_ ;
Coder hasName(string name) { name_ = name ; return this ; }
Coder hasName(string name) { name_ = name ; return this ; }
override int run() {
override int run() {
msleep(rand() & 2047) ;
msleep(rand() & 1023) ;
writefln(">>%s come in.", name_) ;
writefln(">>%s come in.", name_) ;
Dealer single = Dealer.Instance ;
Dealer single = Dealer.Instance ;
msleep(rand() & 1023) ;
for(int i = 0 ; i < 3 ; i++) {
for(int i = 0 ; i < 3 ; i++) {
writefln("%9s got %-s", name_, single.nextState) ;
writefln("%9s got %-s", name_, single.nextState) ;
Line 296: Line 257:
}
}
}
}

void main() {
void main() {
Coder x = new Coder ;
Coder x = new Coder ;
Coder y = new Coder ;
Coder y = new Coder ;
Line 305: Line 267:
z.hasName("Mary").start() ;
z.hasName("Mary").start() ;


x.wait ; y.wait ; z.wait ;
x.wait ; y.wait ; z.wait ;
}</d>
}</d>
Sample Output:
Sample Output:
<pre>>>Mary come in.
<pre>>>Mary come in.
Calling Dealer...
...calling Dealer...
...calling Dealer...
>>Peter come in.
>>Peter come in.
...calling Dealer...
Calling Dealer...
>>Paul come in.
>>Paul come in.
...calling Dealer...
Calling Dealer...
...calling Dealer...
...calling Dealer...
...calling Dealer...
...calling Dealer...
...calling Dealer...
>>Dealer is called to come in!
>>Dealer is called to come in!
Paul got (1)Enjoy
Mary got (1)Enjoy
Peter got (2)Rosetta
Peter got (2)Rosetta
Mary got (3)Code
Mary got (3)Code
Paul got (1)Enjoy
Paul got (1)Enjoy
Mary got (2)Rosetta
Peter got (2)Rosetta
Paul got (3)Code
Paul got (3)Code
Peter got (1)Enjoy
Paul got (1)Enjoy
Mary got (2)Rosetta
Mary got (2)Rosetta
Peter got (3)Code</pre>
Peter got (3)Code</pre>
=={{header|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 [http://www.erights.org/elib/concurrency/vat.html vat] (but can be remotely invoked from other vats).

def aSingleton {
# ...
}

=={{header|Objective-C}}==
===Non-Thread-Safe===

(Using Cocoa's NSObject as a base class)
<pre>
// SomeSingleton.h
@interface SomeSingleton : NSObject
{
// any instance variables
}

+ (SomeSingleton*)sharedInstance;

@end
</pre>

<pre>
// SomeSingleton.m
@implementation SomeSingleton

+ (SomeSingleton*) sharedInstance
{
static sharedInstance = nil;
if(!sharedInstance) {
sharedInstance = [[SomeSingleton alloc] init];
}
return sharedInstance;
}

@end
</pre>
=={{header|Java}}==
=={{header|Java}}==



Revision as of 04:33, 3 March 2008

Task
Singleton
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.
}

D

<d>module singleton ; import std.stdio ; import std.thread ; import std.random ; import std.c.time ;

class Dealer {

 private static Dealer me ;
 static Dealer Instance() {
   writefln("   Calling Dealer... ") ;
   if(me is null) // Double Checked Lock
     synchronized  // this part of code can only be executed by one thread a time
       if(me is null) 
         me = new Dealer ;     
   return me ;
 }
 private static string[] str = ["(1)Enjoy", "(2)Rosetta", "(3)Code"] ;
 private int state ;
 private this() { 
   for(int i = 0 ; i < 3 ; i++) { 
     writefln("...calling Dealer... ") ;
     msleep(rand() & 2047) ;
   }
   writefln(">>Dealer is called to come in!") ;
   state = str.length - 1 ;
 }
 Dealer nextState() {
   synchronized(this) // accessed to Object _this_ is locked ... is it necessary ???
     state = (state + 1) % str.length ;
   return this ;
 }
 string toString() { return str[state] ; }   

}

class Coder : Thread {

 private string name_ ;
 Coder hasName(string name) {  name_ = name ; return this ; }
 override int run() {
   msleep(rand() & 1023) ;
   writefln(">>%s come in.", name_) ;
   Dealer single = Dealer.Instance ;
   msleep(rand() & 1023) ;
   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...
...calling Dealer...
>>Peter come in.
   Calling Dealer...
>>Paul come in.
   Calling Dealer...
...calling Dealer...
...calling Dealer...
>>Dealer is called to come in!
     Mary got (1)Enjoy
    Peter got (2)Rosetta
     Mary got (3)Code
     Paul got (1)Enjoy
    Peter got (2)Rosetta
     Paul got (3)Code
     Paul got (1)Enjoy
     Mary got (2)Rosetta
    Peter got (3)Code

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

Java

Thread-safe

<java> 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

} </java>

Non-Thread-Safe

<java> 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

} </java>