Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Singleton, Static o privada

Iniciado por bnl, 29 de Agosto de 2007, 11:00:05 PM

« anterior - próximo »

Vicente

prompt: a mi la discusión esta me parece interesante, es cierto que se puede vivir sin saber nada sobre memory barriers y demás, pero tampoco está mal saberlo y el que tenga un poco de curiosidad puede haber aprendido bastantes cositas de C# y C++ (yo al menos he aprendido unas cuantas).

bnl

Je je. La verdad es que esto ha derivado bastante desde la pregunta inicial.

A mi me ha parecido tambien interesante la discusion. No conocia la forma de hacerlo que ha comentado Vicente. Supongo que en VB.NET se podrá hacer igual que en C#. ¿Alguien lo sabe?

Prompt, a eso venia la duda inicial. Si en un futuro necesitara 2 instancias no valdria el singleton. En principio no veo la necesidad de tener 2 instancias, pero quiza en un futuro si hiciera falta. Por eso he optado por el singleton que era la idea inicial que tenia. Finalmente puse la clase singleton de la forma tradicional ya que no necesito hilos.

Saludos
Mi web: http://www.brausoft.com/
No sabían que era imposible, así que lo hicieron.

ethernet

Joe Vicente, yo no discuto si en el caso del singleton ganas o pierdes. Es obvio que si para ahcer un singleton tienes que hacer maravillas pero con usando una caracterísitca del lenaguaje lo haces en 30 segundos tomas esta última opción. Pero ante igualdad de condiciones prefiero explícito frente a implícito.

Vicente

Pero es que ethernet no son igualdades de condiciones :) Una implementación es mejor que la otra. Y aquí está la respuesta a todas las dudas de este hilo (me lo ha pasado un compañero del curro):

Citar
Extraido de CLR Via C# 2nd edition, por Jeffrey Richter (pag. 189-191):

"
[...]Also, type constructors should always be prívate. C# makes them private for you automatically. In fact, if you explicitly mark a type constructor as private (or anything else) in your source code, the C# compiler issues the following error: 'error CS0515: SomeValType.SomeValType(): access modifiers are not allowed on static constructors.' Type constructors should be private to prevent any developer-written code from calling them; the CLR is always capable of calling a type constructor.

[...]
The calling of a type constructor is a tricky thing. When the JIT compiler is compiling a method, it sees what types are referenced in the code. If any of the types define a type constructor, the JIT compiler checks if the type's type constructor has already been executed for this AppDomain. If the constructor has never been execute, the JIT compiler emits a call to the type constructor into the native code that the JIT compiler is emitting. If the type constructor for the type has already executed, the JIT compiler does not call since it knows that the type is already initialized. (for an example of this, see the 'Type Constructor Performance' section later in this chapter)

[...]
Now after the method has been JIT compiled, the thread starts to execute it and will eventually get to the code that calls the type constructor. In fact, it is possible that multiple threads will be executing the same method concurrently. The CLR wants to ensure that a type's constructor executes only once per AppDomain. To guarantee this, when a type constructor is called, the calling thread acquires a mutually exclusive thread synchronization lock. So if multiple  threads attempt to simultaneously call a type's static constructor, only one thread will acquire the lock and the other threads will block. The first thread will execute the code in the static constructor. After the first thread leaves the constructor, the waiting threads will wake up and will see that the constructor's code has already been executed. These threads will not execute the code again; they will simply return from the constructor method. In addition, if any of these methods ever get called again the CLR knows that the type constructor has already executed and will ensure that the constructor is not called again.

Note: Since the CLR guarantees that a type constructor executes only once per AppDomain and is thread-safe, a type constructor is a great place to initialize any singleton objects required by the type"

Resumiendo: el CLR sí usa un lock la primera vez que se llama al Type Initializer y el Type Initializer es la forma recomendada de inicializar singletons, aunque en otros lenguajes se haga de otra forma (peor pa ellos :p).

Y no me parece que hacer eso sea nada arcano o misterioso, es simplemente conocer el lenguaje con el que trabajas y aprovechar lo que te ofrece.

bnl: en VB.NET es igual. Y la forma tradicional te está costando un if de regalo que no necesitas hacer :p

Un saludo!

Vicente

ethernet

Es curioso el sistema. Me gustaría ver la implementación porque de alguna forma tiene que marcar que eso ya esté ejecutado, salvo que se modifique el propio bytecode del método para añadir un RET o lo que sea.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.