Frage

Ich habe eine benutzerdefinierte Converter in JSF 1.2 erstellt Date Objekte zu konvertieren. Die Termine haben ein ganz besonderes Format. Ich habe meinen Konverter mit der Kern Java SimpleDateFormat Klasse implementiert, um die Konvertierung zu tun, die Formatierungszeichenfolge in meinem Code Kommentar unten gezeigt. Das alles funktioniert gut.

Meine Frage ist über Thread-Sicherheit. Die SimpleDateFormat API-Dokumente feststellen, dass es nicht sicher ist Thread. Aus diesem Grund habe ich für jede Instanz von meinem Konverter Objekt eine separate Instanz des Datumsformat-Objekt erstellt. Allerdings bin ich mir nicht sicher, ob dies genug. Mein DateFormat Objekt als Mitglied des DTGDateConverter gespeichert wird.

FRAGE: Will zwei Threads Zugriff auf alle gleichzeitig dieselbe Instanz eines Converter Objekt in JSF

Wenn die Antwort Ja ist, dann mein Converter ist wahrscheinlich gefährdet.

/**
 * <p>JSF Converter used to convert from java.util.Date to a string.
 * The SimpleDateFormat format used is: ddHHmm'Z'MMMyy.</p>
 * 
 * <p>Example: October 31st 2010 at 23:59 formats to 312359ZOCT10</p>
 * 
 * @author JTOUGH
 */
public class DTGDateConverter implements Converter {

    private static final Logger logger = 
        LoggerFactory.getLogger(DTGDateConverter.class);

    private static final String EMPTY_STRING = "";

    private static final DateFormat DTG_DATE_FORMAT = 
        MyFormatterUtilities.createDTGInstance();

    // The 'format' family of core Java classes are NOT thread-safe.
    // Each instance of this class needs its own DateFormat object or
    // runs the risk of two request threads accessing it at the same time.
    private final DateFormat df = (DateFormat)DTG_DATE_FORMAT.clone();

    @Override
    public Object getAsObject(
            FacesContext context, 
            UIComponent component, 
            String stringValue)
            throws ConverterException {
        Date date = null;
        // Prevent ParseException when an empty form field is submitted
        // for conversion
        if (stringValue == null || stringValue.equals(EMPTY_STRING)) {
            date = null;
        } else {
            try {
                date = df.parse(stringValue);
            } catch (ParseException e) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Unable to convert string to Date object", e);
                }
                date = null;
            }
        }
        return date;
    }

    @Override
    public String getAsString(
            FacesContext context, 
            UIComponent component, 
            Object objectValue)
            throws ConverterException {
        if (objectValue == null) {
            return null;
        } else if (!(objectValue instanceof Date)) {
            throw new IllegalArgumentException(
                "objectValue is not a Date object");
        } else {
            // Use 'toUpperCase()' to fix mixed case string returned
            // from 'MMM' portion of date format
            return df.format(objectValue).toUpperCase();
        }
    }

}
War es hilfreich?

Lösung

Will zwei Threads Zugriff auf alle gleichzeitig dieselbe Instanz eines Converter Objekt in JSF?

Abhängig von, wie Sie den Konverter. Wenn Sie

<h:inputWhatever>
    <f:converter converterId="converterId" />
</h:inputWhatever>

dann eine neue Instanz wird für jedes Eingabeelement in Sicht erstellt werden, der THREAD (erwartet von dem sehr seltenen Rande Fall ist, dass der Enduser zwei identische Ansichten in zwei Browser-Tabs in der gleichen Sitzung hat und gibt gleichzeitig eine Postbacks auf dem beide Ansichten).

Wenn Sie jedoch verwenden

<h:inputWhatever converter="#{applicationBean.converter}" />

dann die gleiche Instanz über alle Blick auf die gesamte Anwendung gemeinsam genutzt werden, was somit nicht THREAD.

Sie sind das Klonen jedoch eine statische DataFormat Instanz jedes Mal wenn Sie den Konverter erstellen. Dieser Teil ist bereits nicht THREAD. Sie können das Risiko, dass Sie eine Instanz klonen, während sein interner Zustand geändert worden, weil es irgendwo anders verwendet worden ist. Auch eine vorhandene Instanz Klonen ist nicht unbedingt billiger als eine neue Instanz zu schaffen.

würde ich empfehlen, nur es Thread zu erklären (das heißt innerhalb des Verfahrens Block), unabhängig davon, wie Sie den Konverter verwenden. Wenn die Kostspieligkeit der DateFormat jedes Mal zu schaffen, ist ein wichtiges Anliegen (hast du das Profil?), Dann erwägen, sie zu ersetzen durch JodaTime .

Andere Tipps

Datumsformate werden nicht synchronisiert. Es wird empfohlen, getrennt zu erstellen Format-Instanzen für jeden Thread. Wenn mehrere Threads zugreifen ein Format Gleichzeitig muss sie synchronisiert werden nach außen.

Ja, es ist nicht sicher hier fädeln.

Legen Sie es auf ein Verfahren vor Ort und erstellen Instanz pro Thread

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top