獨占鎖(寫鎖)/ 共享鎖(讀鎖)/ 互斥鎖

獨占鎖(寫鎖)/ 共享鎖(讀鎖)/ 互斥鎖

獨占鎖:指該鎖一次只能被一個線程所持有。

  • ReentrantLock、Synchronized都是獨占鎖,并且是可重入鎖(遞歸鎖)
    共享鎖:指該鎖可以被多個線程持有。
  • ReentrantReadWriteLock的讀鎖是共享鎖,寫鎖是獨占鎖。

讀鎖的共享鎖可以保證并發(fā)讀的高效,讀寫,寫讀,寫寫的過程是互斥的。

寫操作:原子+ 獨占,整個過程是不可以被分割、被打斷的。

package com.company;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* 手寫一個緩存
* 1.讀
* 2.寫
* 3.清空
*/
class MyCache{//資源類
   //可見性,禁止指令重排
   private volatile Map<String,Object> map = new HashMap<>();
   //讀寫一體,讀的時候也是只有一個人可以讀,即排著隊讀
   private ReadWriteLock rwlock = new ReentrantReadWriteLock();//可重入的讀寫鎖
   public void put(String key,Object value){
       rwlock.writeLock().lock();
       try
       {
           System.out.println(Thread.currentThread().getName()+"正在寫入"+ key);
           try {TimeUnit.MILLISECONDS.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}
           map.put(key,value);
           System.out.println(Thread.currentThread().getName()+"寫入完成");
       }catch (Exception e){
           e.printStackTrace();
       }finally {
           rwlock.writeLock().unlock();
       }
   }
   public void get(String key) {
       rwlock.readLock().lock();
       try {
           System.out.println(Thread.currentThread().getName() + "正在讀取");
           try {
               TimeUnit.MILLISECONDS.sleep(300);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           Object result = map.get(key);
           System.out.println(Thread.currentThread().getName() + "讀取完成" + result);
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           rwlock.readLock().unlock();
       }
   }
}

/**
* 讀、寫鎖
* 讀,大家可以一起讀
* 寫只允許一個人可以寫:原子、獨占
*
* 讀-讀可以共存
* 讀-寫、寫-寫u可以同時出現(xiàn)
*/
public class ReadWriteLockDemo {
   public static void main(String[] args) {
       MyCache myCache= new MyCache();
       for (int i = 0; i < 3; i++) {
           final int tempInt = i;
           new Thread(()->{
               myCache.put(tempInt+"",tempInt+"");
           },"Thread_No"+i).start();
       }
       for (int i = 0; i < 3; i++) {
           final int tempInt = i;
           new Thread(()->{
               myCache.get(tempInt+"");
           },"Thread_No"+i).start();
       }
   }
}

Console:

  • Thread_No0正在寫入0
  • Thread_No0寫入完成
  • Thread_No2正在寫入2
  • Thread_No2寫入完成
  • Thread_No1正在寫入1
  • Thread_No1寫入完成

寫入與其他操作互斥。

  • Thread_No0正在讀取

  • Thread_No1正在讀取

  • Thread_No2正在讀取

  • Thread_No2讀取完成2

  • Thread_No0讀取完成0

  • Thread_No1讀取完成1

讀讀可以同時進(jìn)行。

讀寫分離,既保證了數(shù)據(jù)的一致性,比較于Synchronized這種重鎖,并發(fā)性得到了提升,因為可以同時讀了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容