2013-03-04 24 views
0

我是java的新手,當我通過java語言閱讀時,我陷入了兩個疑惑。儘管我提到了很多網站,但我仍然不清楚。同步塊中的字符串不變性和等待方法

1)爲什麼string類是不可變的?我看到一些new File(str)導致安全威脅的例子,但我不明白如果字符串是不可變的,它將有助於這種情況。

2)另一個疑問是爲什麼wait,notify和notifyall應該放在synchronized塊中。我知道如果不是它會拋出illegalMonitorException。但我想知道爲什麼它應該在同步塊中的技術背景以及爲什麼沒有在同步塊中等待並且通知可以具有相同的行爲。

請幫我理解。

+1

請不要在一篇文章中合併多個不相關的問題。這兩個問題已經在單獨的問題中討論過了。 – 2013-03-04 20:26:47

+1

for#2 here,請參閱http://stackoverflow.com/q/7019745/217324 – 2013-03-04 20:28:26

+1

for#1參見http://stackoverflow.com/questions/2068804/why-is-string-final-in-java – 2013-03-04 20:29:46

回答

1

爲什麼string類是不可變的?

爲什麼字符串在Java中是不可變的問題是一個老問題,而且這個問題一直存在爭議。在我的書中,我會說它們是不可變的,因爲它們應該是不可變的)。這可能聽起來像一個警察,但讓我解釋一下。

最簡單地說,字符串被用在所有地方,如果它們是可變的,那麼在任何地方都需要很多行李來製作防禦性副本並處理同步等等。讓它們不可變,然後讓幫助器像StringBuilder/StringBuffer一樣改變它們是一個更好的設計選擇(並且在幾種語言中不僅僅是Java)是一個更好的選擇。第二,一切都應該是不可改變的,除非有很好的理由證明可變性。很多許多問題都會在不可變類中消失(特別是與併發有關的問題)。見Effective Java:「類應該是不可變的,除非有一個很好的理由讓它們變爲可變的。如果一個類不能變成不變的,儘可能地限制它的可變性。」

第三,字符串被用在Java的內部,比如類加載機制。使它們不可變使內部過程更簡單,並防止一些安全問題。 (另一個例子,字符串常量在Java中因爲性能的原因被「攔截」:http://en.wikipedia.org/wiki/String_interning,而且這又是一個更穩固的類型。)

總而言之,可能有幾個原因讓設計人員選擇字符串在Java中是不可變的,並且作爲一個日常的程序員它可以幫助你(就像創建新字符串的工具一樣,比如StringBuilder)。

爲什麼等待,通知和notifyall應該在同步塊內?

以下是關於該問題的一些信息:wait(), notify() and notifyAll() inside synchronized statement

基本上它是沒有意義的線程「通知」或「等待」,除非它已經擁有對象的監視器。一般來說,如果你是Java的新手,你可能還想看一些與java.util.concurrent中的併發有關的新工具:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html。通常你可以依賴這些類並避免手工編碼同步,這是非常困難和容易出錯的。

+0

我沒有看到先前在關於String不變性的評論中提到的以前的答案,或者我也會包含一個鏈接(也只是評論;))。不過,我認爲我的答案增加了一點,所以我會放棄它。 – 2013-03-04 20:56:52