2011-03-31 47 views
4

我看到很多類都被添加到Java中,而這些類不是線程安全的。爲什麼添加了非線程安全的java類?

Like StringBuilder不是線程安全的,而StringBuffer是和StringBuilder通過Stringbuffer被退回。

另外各種集合類不是線程安全的。

不是線程安全的好東西嗎?

或者我只是愚蠢的,還不明白線程安全的意思嗎?

回答

11

由於線程安全性使事情變慢,並非所有事情都必須是多線程的。

考慮閱讀這篇文章,以瞭解線程安全的基本知識:

http://en.wikipedia.org/wiki/Thread_safety

當您使用線程/或不夠舒適,可以考慮讀這本書,它有很大的評論:

http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601

+0

那麼,如果我想使用StringBuilder進行多線程? – 2011-03-31 10:18:21

+1

@Lokesh Sah:然後在同步塊中使用'StringBuilder'或使用'StringBuffer'。 – 2011-03-31 10:19:20

+0

@Lokesh Sah:在多線程程序的一個線程中使用'StringBuilder'沒有問題。如果你想追加多個線程中的字符串,那麼你想要什麼語義?爲了在其他線程之間沒有任何內容附加幾個字符串,一段線程擁有'StringBuilder'一段時間。或者你想要任意交錯的附加字符串。在後一種情況下,使用'StringBuffer'。 – jmg 2011-03-31 10:26:11

2

固有的線程安全代碼存在性能開銷。如果你不需要併發上下文的類,但需要高性能,那麼這些原始類並不理想。

+0

你能詳細解釋一下這個線程的安全概念嗎? – 2011-03-31 10:19:04

+0

@Lokesh Sah:如果你有狀態,在這種情況下是一個可變字符串,並且有多個線程作用於它,那麼狀態可能會被破壞。例如。如果字符串是「運行」,則線程A可以通過添加'ning'將其更改爲'運行',而線程B可能想通過將第二個字符從'u'更改爲'a'來將其更改爲'跑'。如果兩個線程同時嘗試此更改,則最終可能會出現損壞狀態,例如在這種情況下'跑步'。爲了防止這種情況,每個線程都需要鎖定可變字符串,查看其當前值,進行必要的更改並釋放鎖。 – 2011-03-31 10:23:02

3

線程安全並不是一個全部或沒有的屬性。十年前,一些書籍建議將一個類的所有方法標記爲synchronized,以使它們安全。這會降低一些性能,但遠不能保證您的整體程序是線程安全的。因此,你的成本有一個可疑的收益。也就是說,爲什麼還有類添加到Java庫中,這些類不是線程安全的。

「使每個方法同步」策略只能保證一個對象的一致性,並且有可能引入死鎖,或者比想象的要弱(想想wait())。

2

的StringBuilder的典型用法是一樣的東西:

return new StringBuilder().append("this").append("that").toString()

都在一個線程中,無需任何同步。

+0

如果你在多個線程中使用StringBuffer,你仍然可以得到'thisthisthathat'或'thisthatthisthat'等。 – 2011-03-31 10:24:26

+0

是的,但是如果StringBuilder被多個線程使用,事情會變得更糟。看看append()方法,並考慮當兩個線程同時修改StringBuilder的狀態時可能發生的情況。 – 2011-03-31 10:32:22

+0

無論哪種方式,它是一個糟糕的設計o在線程中共享一個StringBu * er,你將得到損壞的文本。但是StringBuilder會更糟糕。 ;) – 2011-03-31 11:30:32

4

某些類不適合跨多個線程使用。 StringBuffer就是其中之一。

甚至很難找到什麼時候你會以多線程的方式使用StringBuffer,不能更簡單地實現其他方式。

相關問題