在Java中,關于鎖機制的實現主要可分為兩種:悲觀鎖和樂觀鎖。其中,使用synchronized實現的鎖即為悲觀鎖,而使用ReentrantLock和其它一些類庫實現的鎖則是排他鎖。
悲觀鎖
悲觀鎖的基本思路是:假設最壞的情況,即數據一定會出現沖突,所以在每次訪問共享資源時,都會加上排它鎖(即synchronized)。這樣做雖然能保證數據安全,但同時也會導致性能下降。
//同步代碼塊 synchronized(lock){ //操作共享資源 }
排他鎖
排他鎖是一種更靈活的鎖機制。ReentrantLock就是一種實現排他鎖的類,在Java SE 5.0中引入了它。相較于悲觀鎖,排他鎖允許多個線程同時讀取相同的共享資源,但在寫的時候,必須加鎖,以保證只有一個寫線程進入臨界區。
//申請鎖 ReentrantLock lock = new ReentrantLock(); //加鎖 lock.lock(); try{ //執行等價于同步塊的操作 }finally{ //釋放鎖 lock.unlock(); }
總結
悲觀鎖的鎖粒度大,可以保證數據安全,但是性能較差,不適合高并發的場景。排他鎖相較于悲觀鎖更加靈活,可以根據實際情況進行加鎖,提高了性能和靈活性。