Tengo muchos hilos de procesamiento Trade
objetos donde yo utilizo una RowMapper
a asignar columnas de base de datos a Trade
objeto.
Entiendo SimpleDateFormat
que no es seguro para subprocesos en cualquiera de Java. Como resultado, consigo algún resultado impredecible en startDate
. Por ejemplo, veo que es la fecha endDate
también en startDate
.
Aquí está mi código:
public class ExampleTradeMapper {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MMM-yyyy");
public void map(Trade trade, ResultSet rs, int rowNum) throws SQLException {
trade.setStartDate(getFormattedDate(rs.getDate("START_DATE")));
trade.setEndDate(getFormattedDate(rs.getDate("END_DATE")));
trade.setDescription(rs.getString("DESCRIPTION"));
}
private String getFormattedDate(Date date) {
try {
if (date != null)
return DATE_FORMAT.format(date).toUpperCase();
else
return null;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public class SomeRowMapper extends TradeMapper implements RowMapper<Trade> {
@Override
public Trade mapRow(ResultSet rs, int rowNum) throws SQLException {
Trade trade = new Trade();
map(trade, rs, rowNum);
return trade;
}
}
Mi tamaño del núcleo de la piscina es de aproximadamente 20 para esta aplicación con la máxima aproximadamente 50. Estos hilos se pueden procesando sobre 100s de registros de comercio de la base de datos en algún momento.
¿Cuál sería la mejor manera de hacer esta fecha el formato seguro para hilos? ¿Debo utilizar un reemplazo directo usando FastDateFormat ?
¿Hay una mejor manera alternativa de hacer lo que esta caja fuerte hilo?
tl; dr
En lugar de utilizar cuerdas, uso java.time objetos ( LocalDate
específicamente) intercambiado con su base de datos a través de JDBC 4.2 o posterior.
myResultSet.getObject( // Exchange modern java.time objects with your database.
"START_DATE" ,
LocalDate.class
) // Returns a `LocalDate` object.
.format( // Generate a `String` representing textually the content of this `LocalDate`.
DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US )
)
23-Ene-2018
Siendo los objetos inmutables, los java.time objetos son hilos de proceso seguro por diseño. Puede almacenar en caché los java.time objetos para su uso en las discusiones.
java.time
Hacer seguro para hilos SimpleDateFormat
no lo hacen.
Utilizar las modernas java.time clases que hace años suplantaron a las clases de legado antiguo de fecha y hora problemáticos tales como SimpleDateFormat
, java.util.Date
, java.sql.Date
, y Calendar
.
Los java.time clases están diseñadas para ser thread-safe. Utilizan objetos inmutables patrón, para volver nuevos objetos a partir de los valores de un original en lugar de “mutación” (alteración) del original.
Utilizar objetos inteligentes, las cadenas no mudos
No veo ninguna razón para el uso de cadenas en el código de ejemplo: No en el código de acceso de base de datos, no en su objeto de negocio ( Trade
).
JDBC
A partir de JDBC 4.2, podemos intercambiar java.time objetos con la base de datos. Para una columna de base de datos de un tipo similar al SQL estándar DATE
, utilice la clase LocalDate
. La LocalDate
clase representa un valor de sólo fecha sin la hora del día y sin zona horaria.
myPreparedStatement.setObject( … , myLocalDate ) ;
Recuperación.
LocalDate myLocalDate = myResultSet.getObject( … , LocalDate.class ) ;
objeto de negocio
Su Trade
clase debe ser la celebración variables miembro startDate
y endDate
como LocalDate
objetos, no cadenas.
public class Trade {
private LocalDate startDate ;
private LocalDate endDate ;
…
// Getters
public LocalDate getStartDate() {
return this.startDate ;
}
public LocalDate getEndDate() {
return this.endDate;
}
public Period getPeriod() { // Number of years-months-days elapsed.
return Period.between( this.startDate , this.endDate ) ;
}
// Setters
public void setStartDate( LocalDate startDateArg ) {
this.startDate = startDateArg ;
}
public void setEndDate( LocalDate endDateArg ) {
this.endDate = endDateArg ;
}
@Override
public toString() {
"Trade={ " + "startDate=" + this.startDate.toString() …
}
…
}
No hay necesidad de cadenas, sin necesidad de dar formato a los patrones.
Instrumentos de cuerda
Para los valores de fecha y hora de cambio o almacenar como texto, use el estándar ISO 8601 formatos en lugar de un formato personalizado como se ve en su pregunta.
Los java.time clases utilizan los formatos ISO 8601 de forma predeterminada cuando se analizan / generación de cadenas. Por lo tanto no hay necesidad de especificar un patrón de formatear.
LocalDate ld = LocalDate.parse( "2018-01-23" ) ; // January 23, 2018.
String s = ld.toString() ; // Outputs 2018-01-23.
Para la presentación de una interfaz de usuario, vamos java.time localizan de forma automática. Para localizar, especifique:
FormatStyle
para determinar cuánto tiempo o abreviado debe ser la cadena.Locale
para determinar:- El lenguaje humano para la traducción del nombre del día, el nombre del mes, y tal.
- Las normas culturales de decidir cuestiones de abreviatura, uso de mayúsculas, puntuacion, separadores, y tal.
Ejemplo:
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f =
DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL )
.withLocale( l ) ;
String output = ld.format( f ) ;
Martes, 23 de enero 2018
La DateTimeFormatter
clase es thread-safe, por diseño, como un objeto inmutable. Se podría sostener un caso para ser utilizado a través de los hilos.
sobre java.time
El java.time marco está construido en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como java.util.Date
, Calendar
, y SimpleDateFormat
.
La Joda-Time proyecto, ahora en modo de mantenimiento , asesora a la migración a los java.time clases.
Para obtener más información, consulte el Tutorial de Oracle . Y la búsqueda de desbordamiento de pila durante muchos ejemplos y explicaciones. Especificación es JSR 310 .
Es posible intercambiar java.time objetos directamente con su base de datos. Utilizar un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, sin necesidad de java.sql.*
clases.
Dónde obtener las clases java.time?
- Java SE 8 , Java SE 9 , Java SE 10 , y más tarde
- Incorporado.
- Parte de la API estándar de Java con una aplicación incluida.
- Java 9 añade algunas características menores y correcciones.
- Java SE 6 y Java SE 7
- Gran parte de la funcionalidad de back-java.time está portado a Java 6 y 7 en ThreeTen-Backport .
- Androide
- Las versiones posteriores de Android de haces de implementaciones de los java.time clases.
- Para anteriormente Android (<26), el ThreeTenABP proyecto adapta ThreeTen-Backport (mencionado anteriormente). Ver Cómo utilizar ThreeTenABP ... .
El ThreeTen-Extra proyecto se extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles futuras adiciones a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval
, YearWeek
, YearQuarter
, y más .