2

我想知道在 Java EE 应用程序中使用静态方法的含义是什么。

例如:有一个类可以处理日期的转换、字符串的重新排序等
。这个类中的所有方法都是静态的。
这些方法由 Servlet 使用。

这是否意味着静态方法需要是线程安全的(如果许多用户同时使用应用程序并同时访问静态方法,可能会出现一些问题)?

编辑我想在 Web 应用程序的上下文中了解这一点 - 两个用户是否会同时使用静态方法并相互混淆(静态方法的)结果?

4

3 回答 3

4

只要没有共享类变量,并行访问方法就可以了;例如,如果该方法声明了自己的东西,那么你很好:

public static void thing() {
    String x = "";
    // do stuff with x
}

上面的很好。

String x = "";

public static void thing() {
    // do stuff with x
}

这个不是。

于 2012-09-07T14:06:41.417 回答
2

这是否意味着静态方法需要是线程安全的(如果许多用户同时使用应用程序并同时访问静态方法,可能会出现一些问题)?

仅当存在共享状态时。如果您为每次调用在堆上分配新对象,那么这不是问题。

但我从不喜欢做这种事情,因为立即引入共享状态意味着你有线程安全问题。我更喜欢创建转换器/助手类的实例(对象创建通常在性能方面可以忽略不计)。这立即意味着您是线程安全的(前提是您不共享状态)并且每个实例都可以(例如)在构造时进行自定义,以便在需要时提供不同的行为。

于 2012-09-07T14:04:42.257 回答
1

当然,如果您不保护静态方法并且它们会更改 a 状态,则会出现问题。

考虑这个样本

public class GlobalCount {

    private int count = 0;
    public static void increment() {
       count++; // that is : count = count + 1 (which means some thread may use the old value of count when assigning)
    }
}

如果有多个线程调用increment,您可能会丢失一些增量(也就是说,您count的增量方法可能会小于调用的次数。

所以你必须将你的方法设置为同步:

public static synchronized void increment() {
       count++;
    }

如果您认为您没有共享状态,请注意:许多标准类(例如SimpleDateFormat,正如您所说的日期格式)不是线程安全的,如果从多个线程调用实例可能会失败同时。

所以,一旦你有一个从多个线程访问的静态实例,就要非常小心。

于 2012-09-07T14:05:31.567 回答