2013-05-10 77 views
0

我有一個服務類,它是一個接口的實現,它用Spring作爲服務和單例進行了註釋。我有兩個不同的方法,每個方法創建一個字符串生成器局部變量。我有一個私有方法,它需要一個字符串構建器和一個字符串,並且這兩個參數都是最終變量。此私有方法根​​據在其他字符串變量中找到的信息將信息附加到該字符串構建器。在每個實現的方法中,我都調用該私有方法傳遞本地創建的字符串構建器和必需的字符串。使用Java,這種類型的安裝和線程安全方法調用嗎?

我相信這兩個實現的方法是線程安全的,但我不確定私有方法。那個字符串生成器線程是否安全?是否有參數作爲最終的幫助?我認爲最終是爲了保證線程安全,但同時我認爲最終意味着我不能追加任何東西。

這個stackoverflow問題和答案說,它不會是,但在例子中的參數不是最終的,但也許這並不重要。

Is that StringBuilder variable thread safe in this code?

這裏是什麼,我有一個例子:

@Service 
@Scope("singleton") 
public class SingletonService { 

    @Override 
    public String buildSelect(final Integer id){ 
     StringBuilder sb = new StringBuilder("select * from table "); 
     Map<String,Object> properties = new HashMap<String,Object>(); 
     addWhere(sb,properties,id); 
     return sb.toString(); 
    } 

    @Override 
    public String buildCount(final Integer id){ 
     StringBuilder sb = new StringBuilder("select count(id) from table "); 
     Map<String,Object> properties = new HashMap<String,Object>(); 
     addWhere(sb,properties,id); 
     return sb.toString(); 
    } 

    private void addWhere(final StringBuilder sb, final Map<String,Object> properties, final Integer id){ 
     if(id != null){ 
      sb.append("where id = :id); 
      properties.put("id",id); 
     } 
    } 
} 

回答

1

final具有比使它所以你不能意外分配的東西給變量其他方法簽名中使用時,絕對沒有任何影響在方法裏面。

除此之外......爲什麼不會此代碼是線程安全的?

您傳遞給您的公共方法的唯一方法是Integer,它是不可變的,並且沒有任何其他方法是外部修改的。

所以是的,因爲沒有涉及併發,所以這是線程安全的。

這就是說,這也沒有多大意義。你正在創建一個Map,放入一些東西,然後丟棄它。

+0

是的,看起來有點荒謬。這不是整個班級,只是一個簡單的例子,我沒有徹底移除地圖部分。我比其他任何事情都更擔心字符串的產生。感謝您的回答。關於變量的最後 - 我正在改變變量的值,但間接地通過它的追加方法 - 如果我試圖給它分配一個新的字符串構建器實例,最終會發揮作用嗎? – Elrond 2013-05-10 22:03:39

+0

@Elrond - 正確。 java中的'final'意味着你不能在初始賦值後重新賦值給變量;它與變量所持有的對象沒有任何關係。你並沒有改變變量的*值*,而是使用變量引用的對象。請參閱:http://stackoverflow.com/a/10340003/302916 – 2013-05-10 22:05:31

1

是的,這是線程安全的。

每個線程都有自己的堆棧存放變量。在這種情況下,該變量是一個引用,每個線程一個引用,由該線程創建的StringBuilder的實例。 StringBuilder的實例將在堆中創建,因此可以共享,但您必須顯式傳遞線程之間的引用才能發生。