只使用局部變量的方法是否存在線程問題?有人提到,有局部變量的方法被複制到每個線程堆棧框架中工作,除非使用類級別或靜態引用/變量,否則不需要爲多線程實現同步?在Java中,不使用靜態或類變量的方法需要同步嗎?
回答
如果你的方法只對參數和本地定義的(而不是類成員)變量進行操作,那麼需要擔心的是零同步問題。
但是......
這意味着你用必須生活和你的方法的範圍內死亡只有任何可變引用類型。 (不可變的引用類型是不是這裏有問題。)例如,這是沒有問題的:
int doSomething(int myParameter)
{
MyObject working_set = new MyObject();
interim = working_set.doSomethingElse(myParameter);
return working_set.doSomethingElseAgain(interim);
}
一個MyObject
實例你的方法中創建的,做所有的工作在你的方法,並咳血,等待當你退出你的方法時,由GC來剔除。
此,在另一方面,可能是一個問題:
int doSomething(int myParameter)
{
MyObject working_set = new MyObject();
interim = working_set.doSomethingElse(myParameter);
another_interim = doSomethingSneaky(working_set);
return working_set.doSomethingElseAgain(another_interim);
}
除非你肯定知道發生了什麼事在doSomethingSneaky()
,您可能需要同步的地方。具體而言,您可能必須在working_set
上執行同步操作,因爲doSomethingSneaky()
可能會存儲對本地working_set
對象的引用,並在您仍在執行方法或working_set
方法中的操作時將該引用傳遞給另一個線程。在這裏你必須更加防守。
當然,如果您只使用原始類型,即使調用其他方法,傳遞這些值也不會成爲問題。
您不需要擔心局部變量。但是實例變量是值得關注的。
是否只使用局部變量的方法,不會遇到任何線程問題?
在一個非常簡單的道理沒錯,但讓是明確的 - 我想如果這是唯一真正:
這種方法只使用局部變量是原語或引用可變的情況下,可以不否則通過任何其他方式訪問該方法之外。
這樣的方法只調用線程安全的方法。
的一些方法,這些規則可能被侵犯:
的局部變量可以被初始化爲指向一個對象,這也是該方法外部訪問。例如,局部變量可能指向單例(
Foo bar = Foo.getSingleton()
)。如果將實例作爲參數傳遞給保存對實例的引用的外部方法,則由本地變量持有的本地實例可能會「泄漏」。
沒有實例變量並且只有一個沒有局部變量的方法的類仍然可以調用另一個不是線程安全的類的靜態方法。
該問題是非常通用的,所以請不要指望我的答案有任何特異性。
1_我們需要比靜態方法更小心,而不是說實例方法。
2_ @Justmycorrectopinion是正確的,但他描述的一些術語需要更詳細地闡述爲完美。 (即使靜態方法只適用於局部變量,仍然存在競態條件的可能性。)
3_對於我來說,有一些簡單的規則可以幫助我分析線程安全性。
瞭解封裝在其中的每個組件是否可共享。所以最簡單的解決方案是減少所有變量的範圍,並且如果絕對必要的話只增加範圍,並且如果組件在對象上執行突變,則它通常不是線程安全的。
4_使用工具支持對線程安全執行靜態代碼分析。 (Idea有checkthread插件)。
5_永遠不要使用靜態方法來執行對象變異。如果調用靜態變量導致對象變異,那麼開發人員只是繞開OOPS。
6_始終記錄線程安全性。記住一些方法在開發時可能不需要同步,但可以非常容易地使線程安全。
7_最後但可能是我最重要的一點,請確保大部分對象是不可變的。根據我的經驗,大多數時候,我從來沒有必須讓很多對象變化。 (在極少數情況下,當對象狀態需要更改時,防禦性複製/新建對象創建幾乎總是更好。)
- 1. 當在同步方法或java中使用靜態成員
- 2. Java - 靜態變量不同步
- 3. Java - 同步靜態方法
- 4. java靜態同步方法
- 5. 我可以在java的靜態方法中使用非靜態變量嗎?
- 6. 靜態變量不需要
- 7. 這是靜態方法線程安全或需要同步
- 8. 同一類中的Java靜態變量和非靜態變量
- 9. 關於靜態變量的Java同步方法
- 10. 爲什麼靜態最終變量使用靜態方法初始化需要同步?
- 11. Java在Collections中的靜態方法需要說明嗎?
- 12. 在Dao類中使用靜態方法或非靜態方法?
- 13. 在java中使用靜態同步方法有什麼用途?
- 14. 方法和變量有非靜態需要是靜態錯誤
- 15. 是使用相同的變量不同調用靜態方法
- 16. 在Java中,靜態方法中聲明的變量本身是靜態的嗎?
- 17. 靜態同步方法與非靜態同步方法
- 18. 需要在靜態和非靜態方法中使用實例
- 19. 什麼是靜態方法同步嗎?
- 20. 公共靜態變量或使用意圖類的putExtra方法
- 21. 併發訪問java中的靜態方法,是否需要同步?
- 22. 同步靜態變量的方法是否夠用了?
- 23. 我可以使用類方法來設置靜態變量嗎?
- 24. 從不同的類調用java中的私有靜態變量
- 25. 變量在靜態類中的靜態方法
- 26. 垃圾收集器在java中的靜態變量或方法上工作嗎?
- 27. 如何從靜態類引用main方法中的變量? (java)
- 28. 需要超出靜態變量的類定義嗎?
- 29. java中靜態方法中的靜態變量
- 30. 靜態列表或變量需要鎖定機制嗎?
「任何引用類型」應該可以是「任何_mutable_引用類型」...不可變對象不是問題。 – ColinD 2011-01-22 20:08:26