2012-09-07 41 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,因爲您正在談論日期格式)不是線程安全的,並且如果同時從多個線程調用實例,則可能會失敗。

因此,只要您有一個從多個線程訪問的靜態實例,就要非常小心。