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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top