Java:Java EE应用程序中的静态和线程安全



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

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

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

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

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

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

以上内容很好。

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

这个不是。

这是否意味着静态方法需要是线程安全的(在如果许多用户同时使用该应用程序,并且同时访问静态方法问题)?

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

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

当然,如果您不保护静态方法,并且它们更改了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,正如您所说的日期格式)都不是线程安全的,如果同时从多个线程调用实例,则可能会失败。

因此,一旦有一个静态实例从多个线程访问,就要非常小心。

最新更新