4 回答

TA貢獻(xiàn)1982條經(jīng)驗(yàn) 獲得超2個(gè)贊
那么上面的代碼只是同步了整個(gè) syncHashMap 類還是其中的每個(gè)方法?
不確定同步整個(gè) syncHashMap 類及其中的每個(gè)方法是什么意思。
如果你查看 method 的源代碼Collections.synchronizedMap(hashMap)
,你會(huì)發(fā)現(xiàn)它使用synchronized
關(guān)鍵字來修飾原始映射的每個(gè)方法。這意味著對(duì)于裝飾后的地圖對(duì)象,您一次只能調(diào)用其方法之一。但是不同的地圖,你可以一次調(diào)用它們。
你可以在這里找到它們的用法。ConcurrentHashMap 與同步 HashMap

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超1個(gè)贊
有幾個(gè)術(shù)語涉及您所詢問的主題。
同步化
有許多接口和類可以幫助您在線程之間同步代碼。一個(gè)Semaphore,一個(gè)CyclicBarrier或像BlockingQueue這樣的同步集合。有關(guān)這些類的列表,請(qǐng)參閱java.util.concurrent包。
synchronized
塊也是一種同步方式,但正確使用它需要更多經(jīng)驗(yàn)。
互斥量
不同的語言(和庫)以不同的方式實(shí)現(xiàn)標(biāo)準(zhǔn)互斥鎖。這個(gè)想法保持不變——為了繼續(xù)執(zhí)行特定代碼,一個(gè)互斥令牌,必須獲得一個(gè)互斥體。在 Java 中,這種獲取發(fā)生在進(jìn)入synchronized
塊之前。
線程安全
簡而言之,當(dāng)一個(gè)類的所有方法可以從任意數(shù)量的線程以任意順序同時(shí)訪問時(shí),它就是線程安全的。有幾種方法可以實(shí)現(xiàn)線程安全。例如,字符串是線程安全的。它們不是同步的,但它們是不可變的,這也會(huì)導(dǎo)致線程安全。所有Collections.synchronized*()
方法都返回集合的線程安全包裝器,前提是所有未來*(*請(qǐng)參閱先發(fā)生關(guān)系)對(duì)它們的訪問都是通過這些包裝器執(zhí)行的(這就是為什么初學(xué)者只調(diào)用Collections.synchronized*()
onnew
對(duì)象是一個(gè)很好的規(guī)則。
答案
根據(jù)前面段落的知識(shí),回答你的問題:不,它不同步一個(gè)類。它根本不會(huì)改變?cè)瓉淼?code>Collection實(shí)現(xiàn)。但是,它確實(shí)為該類創(chuàng)建了一個(gè)讀寫線程安全的同步可變代理。

TA貢獻(xiàn)1854條經(jīng)驗(yàn) 獲得超8個(gè)贊
在回答您的問題之前,讓我們重申一些同步的基礎(chǔ)知識(shí)
同步總是在一個(gè)對(duì)象/實(shí)例上。每個(gè)同步實(shí)例都由一個(gè)鎖(稱為互斥鎖)保護(hù)。
任何在對(duì)象上調(diào)用同步方法的線程都必須先獲取該鎖,然后再調(diào)用該方法。
調(diào)用未同步方法的原因不需要此鎖獲取。
回答你的問題:
那么上面的代碼只是同步了整個(gè) syncHashMap 類還是其中的每個(gè)方法?
是的,它確實(shí)。在這里查看Collections.SynchronizedMap 的源代碼即可。注意幾乎每個(gè)方法都有同步(互斥)塊。
如果我們可以在多線程場(chǎng)景中簡單地使用線程安全的集合,例如 ConcurrentHashMap 或 SynchronizedMap,那么 Collections 類中的 Collections.synchronizedMap(hashMap) 和其他類似方法的需求是什么?
好吧,同步每個(gè)方法(包括只讀類型的方法)都有缺點(diǎn)。它不必要地減慢了讀取操作,因此您的觀察是正確的,即使用諸如 ConcurrentHashMap 之類的實(shí)現(xiàn),它只鎖定正在修改集合的方法。只讀方法不同步,因此在具有并發(fā)讀/寫操作的多線程場(chǎng)景中速度更快。
Collections.synchronizedMap 提供的唯一優(yōu)勢(shì)是保留輸入鍵的順序。因此,當(dāng)您需要時(shí),您可以使用 Collections.synchronizedMap。
添加回答
舉報(bào)