假设我的网络应用程序中有一个名为class“Foo”的课程。它有一个initialise()方法,当使用Spring创建bean时调用该方法。然后,initialise()方法尝试加载外部服务并将其分配给字段。如果无法联系该服务,则该字段将设置为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
}

当有人在类“Foo”上调用方法get()时如果它在initialise()方法中启动,将调用该服务。如果服务的字段为null,我想尝试加载外部服务。

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

如果我这样做,可能会出现同步问题吗?

有帮助吗?

解决方案

工具包的答案是正确的。要解决这个问题,只需声明你的Foo的initialise()方法是同步的。你可以将Foo重构为:

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
}

其他提示

是的,您将遇到同步问题。

让我们假设你有一个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
    }
}

你的bean定义如下:

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

问题是你的servlet实例被多个请求线程使用。因此,由service == null保护的代码块可以由多个线程输入。

最好的修复(避免双重检查锁定等)是:

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
    }
}

希望这是有道理的。如果没有,请发表评论。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top