Java -Webanwendung Synchronisierung Frage
-
03-07-2019 - |
Frage
Nehmen wir an, ich habe eine Klasse in meiner Web -App namens Klasse "Foo". Es verfügt über eine initialise () -Methode, die aufgerufen wird, wenn die Bohne mit der Feder erstellt wird. Die initialise () -Methode versucht dann, einen externen Dienst zu laden und einem Feld zuzuweisen. Wenn der Dienst nicht kontaktiert werden konnte, wird das Feld auf Null gesetzt.
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
}
Wenn jemand die Methode Get () in der Klasse "Foo" anruft, wird der Dienst aufgerufen, wenn sie in der initialise () -Methode gestartet wurde. Wenn das Feld für den Dienst null ist, möchte ich versuchen, den externen Dienst zu laden.
public String get() {
if (service == null) {
// try and load the service again
}
// perform operation on the service is service is not null
}
Ist es möglich, dass ich Synchronisationsprobleme habe, wenn ich so etwas tun würde?
Lösung
ToolkitDie Antwort ist korrekt. Um das Problem zu lösen, deklarieren Sie einfach die initialise () -Methode Ihres FOOs für die Synchronisierung. Sie könnten Foo als:
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
}
Andere Tipps
Ja, Sie werden ein Synchronisationsproblem haben.
Nehmen wir an, Sie haben ein einzelnes 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
}
}
Und Ihre Bean -Definition sieht aus wie:
<bean id="myBean" class="com.foo.MyBean" init-method="initialise" />
Das Problem ist, dass Ihre Servlet -Instanz von mehreren Anforderungs -Threads verwendet wird. Daher kann der von Service == NULL bewachten Codeblock von mehreren Threads eingegeben werden.
Das beste Fix (die meiden doppelte Überprüfung usw.) ist:
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
}
}
Hoffe das macht Sinn. Schreiben Sie einen Kommentar, wenn nicht.