Pergunta

Digamos que eu tenho uma aula no meu aplicativo da web chamado Class "Foo". Ele possui um método Initiale () chamado quando o feijão é criado usando o Spring. O método Initiale () tenta carregar um serviço externo e atribuí -lo a um campo. Se o serviço não puder ser contatado, o campo será definido como NULL.

private Service service;

public void initialise() {
    // load external service
    // set field to the loaded service if contacted
    // set to field to null if service could not be contacted
}

Quando alguém chama o método GET () na classe "foo", o serviço será chamado se for iniciado no método Initialise (). Se o campo do serviço for nulo, quero tentar carregar o serviço externo.

public String get() {
    if (service == null) {
        // try and load the service again
    }
    // perform operation on the service is service is not null
}

É possível que eu tenha problemas de sincronização se fizesse algo assim?

Foi útil?

Solução

conjunto de ferramentasA resposta está correta. Para resolver o problema, basta declarar o método Initialise () do Foo () a ser sincronizado. Você pode refatorar foo como:

private Service service;

public synchronized void initialise() {
    if (service == null) {
        // load external service
        // set field to the loaded service if contacted
    }
}

public String get() {
    if (service == null) {            
        initialise(); // try and load the service again
    }
    // perform operation on the service is service is not null
}

Outras dicas

Sim, você terá um problema de sincronização.

Vamos supor que você tenha um único servlet:

public class FooServlet extends HttpServlet {

    private MyBean myBean;

    public void init() {
        myBean = (MyBean) WebApplicationContextUtils.
            getRequiredWebApplicationContext(getServletContext()).getBean("myBean");
    }

    public void doGet(HttpRequest request, HttpResponse response) {
        String string = myBean.get();
        ....
    }

}

class MyBean {
    public String get() {
        if (service == null) {
            // try and load the service again
        }
        // perform operation on the service is service is not null
    }
}

E sua definição de feijão se parece:

<bean id="myBean" class="com.foo.MyBean" init-method="initialise" />

O problema é que sua instância do servlet é usada por vários threads de solicitação. Portanto, o bloco de código guardado pelo serviço == NULL pode ser inserido por vários threads.

A melhor correção (evitando travamentos verificados etc.) é:

class MyBean {
    public synchronized String get() {
        if (service == null) {
            // try and load the service again
        }
        // perform operation on the service is service is not null
    }
}

Espero que isso faça sentido. Deixe um comentário, se não.

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