Pergunta de sincronização de aplicativos da web java
-
03-07-2019 - |
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?
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.