簡體   English   中英

確保Java方法是線程安全的

[英]to ensure a java method is thread safe

僅使用局部變量而不使用實例變量是否足夠? 因此僅使用堆棧上的內存(每個線程)。

但是,當您創建方法本地的新MyObject時會發生什么。 新對象不是在堆上創建的嗎? 它是線程安全的,因為對其的引用是本地的(線程安全)嗎?

它是線程安全的,因為如果僅由該特定方法中的變量引用(如您所說,它是局部變量),則其他任何線程都不可能引用該對象,因此無法更改該對象。

想象你和我是海盜(線程)。 您去將贓物(對象)埋在島(堆)上,並保留一張地圖(參考)。 我碰巧用同一個島埋藏我的戰利品,但是除非您給我您的地圖,否則我將在整個島上進行挖掘(在Java島上是不允許的),所以我不會弄亂您的藏身之處。

您的新MyObject是線程安全的,因為對方法的每次調用都會在堆上創建自己的本地實例。 沒有一個調用引用一個通用方法。 如果有N個調用,則表示堆上有N個MyObject實例。 方法退出后,只要您不將其返回給調用方,每個實例都可以使用GC。

好吧,讓我問一個問題:將方法限制為局部變量是否意味着您的方法無法與另一個線程共享資源? 如果不是這樣,那么顯然這通常不足以保證線程安全。

如果您擔心另一個線程是否可以修改您在另一個線程中創建的對象,那么您唯一需要擔心的就是永遠不要從線程中泄漏對該對象的引用。 如果實現了這一點,則對象將在堆中,但是沒有其他線程能夠引用它,所以沒關系。

編輯

關於我的第一條語句,這是一個沒有實例變量的方法:

public void methodA() {
    File f = new File("/tmp/file");
    //...
}

這並不意味着兩個線程之間不能共享資源:-)。

Threre無法訪問其他線程來訪問此類對象引用。 但是,如果該對象不是線程安全的,則將損害總體線程安全。

例如,考慮MyObject是HashMap。

如果它在堆中不是線程安全的,則該論點無效。 不能通過指針算法訪問堆,因此它不會影響對象的實際存儲位置(除了ThreadLocal之外)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM