java车次信息_从火车站车次公示栏来学Java读写锁
Java多線程并發之讀寫鎖
本文主要內容:讀寫鎖的理論;通過生活中例子來理解讀寫鎖;讀寫鎖的代碼演示;讀寫鎖總結。通過理論(總結)-例子-代碼-然后再次總結,這四個步驟來讓大家對讀寫鎖的深刻理解。
本篇是《凱哥(凱哥Java:kagejava)并發編程學習》系列之《Lock系列》教程的第七篇:《Java并發包下鎖學習第七篇:讀寫鎖》。
一:讀寫鎖的理論
什么是讀寫鎖?
多個線程同時讀一個資源類是沒有任何問題的,所以為了滿足在并發的情況下,讀取共享資源應該是可以同時進行的;但是,如果一個線程想要去寫共享資源,就不應該再有其他線程可以對該共享資源進行讀或者是寫操作了。
即讀寫鎖在同一時刻可以允許多個多線程訪問,但是在寫線程訪問的時候,所有的讀線程和其他寫線程都會被阻塞。讀寫鎖實際維護了一對鎖,一個讀鎖,一個寫鎖,通過分離讀鎖和寫鎖,使得其并發性比獨占式鎖(排他鎖)有了很大的提升。
為什么需要讀寫鎖?
通過前面文章的學習,我們知道了ReentrantLock(下文簡稱:RLock)對象了。Rlock比起synchronized(下文簡稱Sync)來說有三個優點:RLock可以被中斷;RLock可以有公平鎖;RLock可以綁定多個條件。那么既然RLock比Sync有這么多優點,為什么還需要讀寫鎖呢?
那是因為RLock是獨占式(排他) 鎖,即當線程1獲取到資源的時候,其他線程不能再來操作共享資源了。就算是RLock的操作是讀取的時候,其他線程也不能讀取共享資源的操作。這在現實生活中是不符合邏輯的(在下文神話中讀寫鎖的例子中我們就能體會到為什么不符合邏輯的),而且性能也比較慢。所以就有了讀寫鎖的出現。
二:讀寫鎖的理解
生活中讀寫鎖的例子
例子一:我們大家去火車站乘車的時候,有個大大的公示屏幕,會告訴大家當前車次是否晚點。顯示屏是給給所有乘客看的,如果火車晚點,對應車次后面就會被修改成晚點大約xxx分鐘。這個修改的動作只能是火車站內部人員來操作的,我們乘客是不能操作的。這個過程,站在并發角度來分析的的話:電子屏幕是共享數據;千千萬萬的乘客是不同的線程;火車站內部工作人員也是不同的線程;乘客是讀資源的線程,當一個線程來讀取的時候,其他線程也可以讀取操作的;火車站內部工作人員修改火車信息的時候,同時只能有一個工作人員來修改,不能兩個都來修改。如果兩個都來修改的話,上一秒顯示晚點1min,下一秒顯示正常。這個是不行的,乘客有可能會錯過乘車的。所以修改的時候同時只能由一個工作人員來修改。
例子二:我們在玩王者榮耀的時候,有時候會遇到停服更新的。在不更新前,所有玩家都可以玩,當停服更新的時候,所有玩家就不能玩了。這個操作在并發角度來說:千千萬萬的玩家是讀共享資源的;游戲維護者是寫操作的。當停服更新的時候,讀操作就被阻塞了,只能等寫操作,也就是更新完成后,才可以接著玩。
通過上面兩個例子我們可以分析到讀寫鎖的三個參與者:共享資源;讀對象;寫對象。而且讀和寫一般是分離的。
三:讀寫鎖的代碼演示
我們就用火車站進站案例來模擬:
未使用鎖的時候
先來看看屏幕對象:
再來看看多個工作人員更新操作及多個乘客獲取操作:
查看運行結果:
從運行結果中,我們可以發現當工號未13的還沒有更新完車次信息的時候,工號12和14的員工也來更新了。這種操作是不允許的。因為寫操作要原子性,要獨占。當工作人員甲在修改的時候車次信息的時候,其他工作人員不能同時修改同一個車次信息了。而且從乘客獲取車次信息的數據來看,獲取到的只是工號是13的。這個時候獲取到的數據不一定是正確的了。所以,不使用鎖是不行的。
使用排他鎖
如果使用獨占式做的話,我們查看運行結果:
從運行結果來看,再讀取的時候,需要一個一個讀取的。當16號乘客查看的時候,17號乘客是不能查看的。這個是不符合實際業務邏輯的。所以,獨占式(排他鎖)RLock在這里不適合。我們再來看看讀寫鎖:
使用讀寫鎖
先來看看使用讀寫鎖的屏幕對象
再來看看運行結果:
從運行結果中,我們可以看到,工作人員是一個一個的操作完成的。當14號操作完成之后,13號和12號才可以操作的。這個符號我們正常的業務。乘客讀取的時候,讀取到的都是最后一次更新,這個也符合我們的業務。所以,通過讀寫鎖來操作車站屏幕是可以的。
四:讀寫鎖總結
4.1:wrLock類對象
同樣包含了公平鎖和非公平鎖。
其中ReadLock是讀鎖對象;WriteLock是寫鎖對象。
4.2:使用語法
讀操作使用ReadLock
編輯
寫操作的時候,使用WriteLock對象:
4.3:總結
讀寫鎖(ReentrantReadWriteLock),凱哥就簡寫rwLock。也可以實現公平和非公平的。其內部維護了一對鎖:一個讀鎖(ReadLock對象),一個寫鎖(writeLock對象),通過讀寫分離的方式來提高并發性能。讀寫鎖也叫共享鎖。其共享是在讀數據的時候,可以讓多個線程同時進行讀操作的。在寫的時候具有排他性,其他讀或者寫操作都要被阻塞。
一般情況下,讀寫鎖的性能都會比排他鎖性能好,那是因為,大多數場景讀操作多于寫操作的。在讀多與寫的場景下,讀寫鎖能夠提供比排他鎖更好的并性能和吞吐量。
???????????????????????????????????????????????????????????????????????歡迎來聊~
總結
以上是生活随笔為你收集整理的java车次信息_从火车站车次公示栏来学Java读写锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: applicationContext.x
- 下一篇: 《战神》创意总监:《战神:诸神黄昏》即将