2012-09-07 60 views
2

我想知道在Java EE应用程序中使用静态方法会产生什么样的影响。Java:Java EE应用程序中的静态和线程安全

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

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

编辑我想知道关于这个在Web应用程序的上下文中 - 两个用户会同时击中静态方法并混淆了每个其他结果(静态方法)?

+0

关于标签:我不认为这里有任何[java-ee]相关。 –

+0

它是一个有多个用户的jee应用程序。 –

回答

3

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

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

以上是好的。

String x = ""; 

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

这一个不是。

+0

Aka方法范围变量或局部变量。 –

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比增量方法被调用的次数少。

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

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

如果你认为你没有共享状态,小心:许多标准类(例如SimpleDateFormat,因为您正在谈论日期格式)不是线程安全的,并且如果同时从多个线程调用实例,则可能会失败。

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