Pregunta

Así que estoy pensando en la construcción de un proyecto de pasatiempo, uno de tipo de cosas, sólo para poner al día mi programación / diseño.

Se trata básicamente de un multi-hilo de araña, la actualización de la misma estructura de datos objeto-> int.

Por lo que es sin duda una exageración de utilizar una base de datos para esto, y lo único que podía pensar es un producto único hilo de seguridad utilizado para contener la estructura de datos. http : //web.archive.org/web/20121106190537/http: //www.ibm.com/developerworks/java/library/j-dcl/index.html

¿Hay un enfoque diferente que debe buscar a?

¿Fue útil?

Solución

bloqueo doble comprobación ha demostrado ser incorrecta y defectuosa (como mínimo en Java). Hacer una búsqueda o buscar en la entrada de Wikipedia para la razón exacta.

En primer lugar está la corrección del programa. Si el código no es seguro para subprocesos (en un entorno multi-hilo), entonces se ha roto. La corrección es lo primero antes de la optimización del rendimiento.

Para ser correcto que tendrá que sincronizar todo el método getInstance

public static synchronized Singleton getInstance() {
   if (instance==null) ...
}

o estáticamente inicializarlo

private static final Singleton INSTANCE = new Singleton();

Otros consejos

El uso de inicialización perezosa para la base de datos en un rastreador web no es probable que valga la pena. inicialización perezosa añade complejidad y un golpe de velocidad en curso. Un caso en el que se justifica es cuando hay una buena probabilidad nunca serán necesarios los datos. También, en una aplicación interactiva, que se puede utilizar para reducir el tiempo de puesta en marcha y dar el ilusión de la velocidad.

Para una aplicación no interactiva como una tela de rastreador, que seguramente tendrá su base de datos de existir de inmediato, la inicialización perezosa es un mal ajuste.

Por otro lado, un rastreador web es fácilmente paralelizable, y se beneficiarán enormemente de ser multi-hilo. Utilizarlo como un ejercicio para dominar la biblioteca java.util.concurrent sería extremadamente valiosa. Específicamente, mira ConcurrentHashMap y < a href = "http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentSkipListMap.html" rel = "noreferrer"> ConcurrentSkipListMap, que permitirá que múltiples hilos a leer y actualizar un mapa compartido.

Cuando a deshacerse de inicialización perezosa, el patrón Singleton simple es algo como esto:

class Singleton {

  static final Singleton INSTANCE = new Singleton();

  private Singleton() { }

  ...

}

El final palabra clave es la clave aquí. Incluso si usted proporciona un static "captador" para el singleton en lugar de permitir el acceso de campo directo, haciendo que el final Singleton ayuda a garantizar la exactitud y permite la optimización más agresiva por el compilador JIT.

Si su vida dependía de unos pocos microsegundos entonces yo le aconsejaría usted para optimizar su recurso de bloqueo a donde realmente importaba.

Sin embargo, en este caso la palabra clave aquí es Proyecto manía !

Lo que significa que si ya ha sincronizado todo el getInstance () método que va a estar bien en el 99,9% de todos los casos. Yo no recomendaría hacerlo de otra manera.

Más tarde, si pruebas por medio de perfiles que la getInstance () de sincronización es el cuello de botella de su proyecto, a continuación, puede seguir adelante y optimizar la concurrencia. Pero realmente dudo que causar problemas.

Jeach!

Trate de la Bill Pugh solución de inicialización en el lenguaje titular de la demanda. La solución es la más portable a través de diferentes compiladores Java y máquinas virtuales. La solución es seguro para subprocesos sin necesidad de construcciones de lenguaje especiales (es decir volátil y / o sincronizado).

http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh

como Joshua Bloch sostiene en su libro "efectiva 2ª edición java" También estoy de acuerdo que un solo tipo de elemento de enumeración es la mejor manera de poner en práctica un conjunto unitario.

public enum Singleton {
  INSTANCE;

  public void doSomething() { ... }
}

Si nos fijamos en la parte inferior de dicho artículo, verá la sugerencia de que sólo tiene que utilizar un campo estático. Eso sería mi inclinación: que realmente no necesita de instancias perezoso (por lo que no es necesario getInstance() a ser a la vez un descriptor de acceso y un método de fábrica). Lo que desea es asegurarse de que tiene una y sólo una de estas cosas. Si realmente necesita el acceso global a una tal cosa, que haría uso de ejemplo de código que hacia la parte inferior :

class Singleton
{
  private Vector v;
  private boolean inUse;
  private static Singleton instance = new Singleton();

  private Singleton()
  {
    v = new Vector();
    inUse = true;
    //...
  }

  public static Singleton getInstance()
  {
    return instance;
  }
}

Tenga en cuenta que el Singleton está construido durante la instalación de campos estáticos. Esto debe trabajar y no hacer frente a los riesgos de roscado de cosas potencialmente mala sincronización.

Dicho todo esto, tal vez lo que realmente necesita es una de las estructuras de datos compatibles con el proceso disponibles en el JDK modernas. Por ejemplo, yo soy un gran fan de la ConcurrentHashMap : (FTW). hilo de seguridad además de que no tiene que escribir el código

¿Por qué no crear una estructura de datos que se pasa a cada uno de los hilos como la inyección de dependencias. De esta manera no es necesario un conjunto unitario. Todavía se necesita para hacer el hilo de seguridad.

El artículo al que hizo referencia sólo habla de lo que la creación del objeto Singleton, presumiblemente, una colección en este caso, el hilo de seguridad. También es necesario una colección segura para subprocesos de manera que las operaciones de recogida también funcionan como se esperaba. Asegúrese de que la colección subyacente en el singleton se sincroniza, tal vez mediante un ConcurrentHashMap .

Consulte este artículo Implementación del patrón Singleton en C #

public sealed class Singleton
{
    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return Nested.instance;
        }
    }

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

¿Qué hay de:

public static Singleton getInstance() {
  if (instance == null) {
    synchronize(Singleton.class) {
      if (instance == null) {
         instance = new Singleton();
      }
    }
  }

  return instance;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top