Singleton: Difference between revisions

From Rosetta Code
Content added Content deleted
(+D)
m (→‎{{header|D}}: the mask after rand() should be in form of 0xfff instead of 0x1000)
Line 126: Line 126:
for(int i = 0 ; i < 6 ; i++) {
for(int i = 0 ; i < 6 ; i++) {
writefln("...calling Dealer... ") ;
writefln("...calling Dealer... ") ;
msleep(rand() & 2048) ;
msleep(rand() & 2047) ;
}
}
me = new Dealer ;
me = new Dealer ;
Line 151: Line 151:
Coder hasName(string name) { name_ = name ; return this ; }
Coder hasName(string name) { name_ = name ; return this ; }
override int run() {
override int run() {
msleep(rand() & 512) ;
msleep(rand() & 2047) ;
writefln(">>%s come in.", name_) ;
writefln(">>%s come in.", name_) ;
Dealer single = Dealer.Instance ;
Dealer single = Dealer.Instance ;
msleep(rand() & 512) ;
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) ;
msleep(rand() & 1024) ;
msleep(rand() & 1023) ;
}
}
return 0 ;
return 0 ;
Line 174: Line 173:
}</d>
}</d>
Sample Output:
Sample Output:
<pre>>>Peter come in.
<pre>>>Mary come in.
...calling Dealer...
...calling Dealer...
>>Peter come in.
...calling Dealer...
...calling Dealer...
>>Paul come in.
...calling Dealer...
...calling Dealer...
...calling Dealer...
...calling Dealer...
...calling Dealer...
...calling Dealer...
>>Paul come in.
>>Mary come in.
...calling Dealer...
...calling Dealer...
>>Dealer is called to come in!
>>Dealer is called to come in!
Mary got (1)Enjoy
Paul got (2)Rosetta
Mary got (3)Code
Peter got (1)Enjoy
Paul got (2)Rosetta
Mary got (3)Code
Paul got (1)Enjoy
Paul got (1)Enjoy
Peter got (2)Rosetta
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</pre>
Peter got (3)Code</pre>

Revision as of 10:05, 2 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.

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

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