簡體   English   中英

Java使用對象作為監視器,那不是很重的對象嗎?

[英]Java uses object as monitor, isn't that object too heavy weight?

我是用Java語言規范17.1閱讀的:

“ Java中的每個對象都與一個監視器關聯,線程可以鎖定或解鎖監視器。”

為什么一定要這樣? 這不是使Java對象太重嗎? 我不知道為什么像字符串這樣的對象自然應該是監視器!

編輯:

我想一想,是的,Java有一個關鍵字sync ,因為每個對象都可以有一個同步方法,因此有必要將每個對象與Monitor關聯。

但這仍然不是一個很好的解決方案,通常一個類需要一個互斥量,除了pojo類非常簡單之外。

您的假設中有一些道理,在經典著作“ Java Concurrency in Practice”(由權威專家Brian Goetz,Tim Peierls,Joshua Bloch,Joseph Bowbeer,David Holmes,Doug Lea撰寫)中,他們寫道:

每個對象都有內置鎖的事實只是一種方便,因此您無需顯式創建鎖對象。 回想起來,這個設計決定可能是一個糟糕的決定:不僅會造成混亂,而且會迫使JVM實現者在對象大小和鎖定性能之間進行權衡。

(第2.4章:帶鎖的防護狀態)

您的基本問題是假設每個對象都內置有某種Monitor ,等待其被某些代碼使用。 實際上,大多數對象從不用作監視器,因此在使用監視器之前不必創建它們。 與其將這個功能實現為每個具有private Monitor monitor字段的HashMap<object, Monitor> monitors不如將其視為具有全局HashMap<object, Monitor> monitors的JVM來實現。

可能的實現方式是:每當輸入synchronized塊時,JVM都會在映射( monitors )中查找同步對象。 如果找到它,則可以使用監視器。 如果找不到,則會進入地圖專用的關鍵部分。 然后,它再次查找該對象,因為在上一次檢查和進入關鍵部分之間可能已經有另一個線程創建了該對象。 如果仍然不存在,它將為同步對象創建監視器,並離開關鍵部分。

這是使幾乎所有線程安全的一種非常聰明的方法。 我認為沉重的體重有些主觀; 在Java中,例如,對象只獲得一項須予公布等待隊列,同時指定互斥明確與完成synchronize

C#使用類似的方法來增強線程安全性,因此顯然MS也認為這是一個非常聰明的解決方案。 替代是什么? 手寫信號量和互斥量? 在Java中,考慮到大多數生產級應用程序(即服務器,服務等) 必須是多線程的,這將是一場噩夢。 讓語言為您完成所有困難/無聊的工作真是太棒了。

線程同步對於確保正確的結果是必要的,因為它們可能處於競爭狀態。

好吧,如果它不如LCD或CRT顯示器那么重,那還好嗎?

沒那么重 對象很便宜。

我同意任何對象都可以是鎖的概念非常令人困惑。 許多人認為, synchronized(obj)可以防止同時訪問obj 如果我們將鎖與國家/地區分開,則這種誤解的可能性較小。

Java內存模型中的文字不顯示使用任意對象或任何對象作為同步原語的任何重要性。 為此目的使用對象也許是一種經濟的設計。

它也可以將整數用作鎖。 synchronized(493725)實際上是因為每個對象在內部都與一個整數(其地址)相關聯,因此JVM可能synchronized(493725) 未同步的對象的開銷為零。

使用java.util.concurrent類,即使您不喜歡它,也不再需要此類synchronized(obj)

暫無
暫無

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

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