2011-09-08 14 views
12

Dado un tiempo en milisegundos, podemos crear XMLGregorianCalendar usando el siguiente fragmento de código.El uso de DataTypeFactory al crear XMLGregorianCalendar golpea mal el rendimiento

GregorianCalendar greCal = new GregorianCalendar(); 
greCal.setTimeInMillis(timeInMilliseconds); 
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(greCal)); 

Pero el problema es que golpea el rendimiento mal.

http://www.java.net/node/666491

hay un error presentada por esto con sol, pero que no se han enumerado soluciones provisionales. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6466177

Intenté buscar otra alternativa, pero fue en vano. ¿Alguno de ustedes tiene una alternativa para hacer lo mismo?

Gracias

Raman

Respuesta

11

La parte costosa es DatatypeFactory.newInstance(), se muestra a la derecha en la parte superior cuando el perfil de la aplicación. En nuestro caso almacenamos DatatypeFactory como variable estática y pudimos eludir la inicialización repetida. Esto debería funcionar porque se supone que la implementación de DatatypeFactory que utilizamos es segura para subprocesos (como se indica en el informe de errores). Estoy de acuerdo en que existe la posibilidad de que esto cambie según la implementación utilizada. Así que recomendaré hacer una doble comprobación.

private static DatatypeFactory datatypeFactory; 
static{ 
    try { 
     datatypeFactory = DatatypeFactory.newInstance(); 
    } catch (DatatypeConfigurationException e) { 
     throw new RuntimeException("Init Error!", e); 
    } 
} 

public void foo(long timeInMilliseconds){ 
    GregorianCalendar greCal = new GregorianCalendar(); greCal.setTimeInMillis(timeInMilliseconds); 
    XMLGregorianCalendar xmlGregorienCalendar = datatypeFactory.newXMLGregorianCalendar(greCal); 
    // ... 
} 
+0

para evitar asumir que la impl de DatatypeFactory permanecerá segura para subprocesos, considere utilizar un ThreadLocal: – Nikita

+6

En teoría sí, pero la implementación actual es segura para hilos, y se honesto alguien w Tendría que esforzarse mucho para que no sea enhebrable. (Si solo el mismo tipo escribiera SimpleDateFormat, el mundo sería un lugar más feliz). –

9

ya que como se mencionó @VivaceVivo DataFactory.newInstance() es caro y impl no garantiza que sea seguro para subprocesos, considerar el uso de un ThreadLocal:

final private static ThreadLocal<DatatypeFactory> datatypeFactoryHolder = new ThreadLocal<DatatypeFactory>() 
    { 
     @Override 
     protected DatatypeFactory initialValue() 
     { 
      try 
      { 
       return DatatypeFactory.newInstance(); 
      } catch (DatatypeConfigurationException e) 
      { 
       throw new IllegalStateException("failed to create " + DatatypeFactory.class.getSimpleName(), e); 
      } 
     } 
    }; 

    public static XMLGregorianCalendar dateToXMLGregorianCalendar(Date date) 
    { 
     GregorianCalendar c = new GregorianCalendar(); 
     c.setTime(date); 
     return datatypeFactoryHolder.get().newXMLGregorianCalendar(c); 
    } 
} 

..as siempre y cuando no lo hace cuidado si los hilos retienen un objeto adicional o tienen una manera de borrar ThreadLocalMap cuando sea necesario

Cuestiones relacionadas