Pergunta

Como existe o problema de bloqueio verificado duas vezes, precisamos usar a sincronização para garantir o acesso simultâneo ao seguinte método (org.apache.struts.util.messageSources Class):

Instanciação preguiçosa

public synchronized static MessageResources getMessageResources(String config) {

    if (defaultFactory == null) {
        defaultFactory = MessageResourcesFactory.createFactory();
    }

    return defaultFactory.createResources(config);
}

Por que não usar:

Instanciação ansiosa

static {

    // Construct a new instance of the specified factory class
    try {
        if (clazz == null)
            clazz = RequestUtils.applicationClass(factoryClass);
        MessageResourcesFactory defaultFactory =
            (MessageResourcesFactory) clazz.newInstance();
    } catch (Exception e) {
        LOG.error("MessageResourcesFactory.createFactory", e);
    }

}

E depois:

public static MessageResources getMessageResources(String config) {

    return defaultFactory.createResources(config);
}

Isso permitiria acesso simultâneo ao método getMessageSources, que pelo menos no meu caso pode ser chamado algumas vezes.

As implicações quando não estão usando sincronizadas estão aqui:

http://en.wikipedia.org/wiki/double-checked_locking

Foi útil?

Solução 4

Eu acho que é uma maneira de os suportes garantir que funcione bem quando no modo multi-thread, não importa se a pessoa substituindo org.apache.struts.util.messageSources Define o createresources (configuração de string) como sincronizado ou não.

Outras dicas

É MessageResourcesFactory discussão segura? o synchronized o método protege a configuração do campo e o createResources Chamada de método. Se for seguro, o bloqueio poderá ser movido para cobrir apenas definir o campo e deixar a chamada do método fora da seção crítica.

A sobrecarga incorrida por métodos sincronizados em uma JVM moderna é tão pequena que se torna insignificante. As chamadas subsequentes para o método sincronizado de fábrica de initação preguiçosas serão tão rápidas quanto as chamadas para um método não sincronizado.

Em termos de código, a abordagem de initação preguiçosa é mais simples e fácil de entender (na minha opinião) do que usar um bloco de inicializador estático. Além disso, quando os blocos estáticos do init falham, pode ser muito confuso descobrir onde e por quê.

A menos que haja alguma razão para MessageResourceFactory Não pode ser inicializado desde o início (por exemplo, certos recursos do servlet precisam ser inicializados primeiro), acho que gosto mais da sua solução. Eu acho que não há razão para a equipe de struts carregar preguiçosamente a fábrica, exceto isso, é isso que o desenvolvedor em particular que trabalhou isso está acostumado a fazer (as pessoas tendem a carregar preguiçosamente singletons, mesmo quando não é necessário).

Você já tentou enviar um relatório de bug e propor sua solução?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top