Domanda di sincronizzazione dell'applicazione Web Java
-
03-07-2019 - |
Domanda
Diciamo che ho una classe nella mia app web chiamata class " Foo " ;. Ha un metodo initialise () che viene chiamato quando il bean viene creato usando Spring. Il metodo initialise () quindi tenta di caricare un servizio esterno e assegnarlo a un campo. Se non è stato possibile contattare il servizio, il campo verrà impostato su 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 qualcuno chiama il metodo get () sulla classe " Foo " il servizio verrà richiamato se è stato avviato nel metodo initialise (). Se il campo per il servizio è nullo, voglio provare a caricare il servizio esterno.
public String get() {
if (service == null) {
// try and load the service again
}
// perform operation on the service is service is not null
}
È possibile che io abbia problemi di sincronizzazione se dovessi fare qualcosa del genere?
Soluzione
?? toolkit è corretta. Per risolvere il problema, basta dichiarare il metodo initialise () di Foo come sincronizzato. Potresti refactificare Foo come:
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
}
Altri suggerimenti
Sì, avrai un problema di sincronizzazione.
Supponiamo che tu abbia un servlet singolo:
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 la definizione del tuo bean è simile a:
<bean id="myBean" class="com.foo.MyBean" init-method="initialise" />
Il problema è che l'istanza del servlet è utilizzata da più thread di richiesta. Pertanto, il blocco di codice protetto da service == null può essere inserito da più thread.
La migliore soluzione (evitando il doppio controllo, ecc.) è:
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
}
}
Spero che abbia senso. In caso contrario rilascia un commento.