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

时间:2012-09-07 14:01:59

标签: java java-ee thread-safety

我想知道在Java EE应用程序中使用静态方法有什么影响。

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

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

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

3 个答案:

答案 0 :(得分:3)

只要没有共享的类变量,

并行访问方法就没问题;例如如果方法声明了自己的东西,那你很好:

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

以上情况很好。

String x = "";

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

这个不是。

答案 1 :(得分:2)

  

这是否意味着静态方法需要是线程安全的(在那里   如果许多用户同时使用该应用程序,那么   在可能存在的情况下同时访问静态方法   问题)?

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

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

答案 2 :(得分:1)

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

考虑这个样本

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小于调用增量方法的次数。

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

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

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

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