天天看點

JUC——ReadWriteLock讀寫鎖1:ReadWriteLock讀寫鎖介紹2:ReadWriteLock讀寫鎖示範

文章目錄

  • 1:ReadWriteLock讀寫鎖介紹
  • 2:ReadWriteLock讀寫鎖示範

1:ReadWriteLock讀寫鎖介紹

ReadWriteLock是JDK5中提供的讀寫分離鎖。讀寫分離鎖可以有效地幫助減少鎖競争,提升系統性能。用鎖分離的機制來提升性能非常容易了解,比如線程A1、 A2. A3進行寫操作,B1、B2、B3進行讀操作,如果使用重入鎖或者内部鎖,從理論上說所有讀之間、讀與寫之間、寫和寫之間都是串行操作。當B1進行讀取時,B2、 B3 則需要等待鎖。由于讀操作并不對資料的完整性造成破壞,這種等待顯然是不合理的。是以,讀寫鎖就有了發揮功能的餘地。

在這種情況下,讀寫鎖允許多個線程同時讀,使得B1、B2、B3之間真正并行。但是,考慮到資料完整性,寫寫操作和讀寫操作間依然是需要互相等待和持有鎖的。總的來說,讀寫鎖的通路限制情況如下

  • 讀-讀不互斥: 讀讀之間不阻塞。
  • 讀-寫互斥: 讀阻塞寫,寫也會阻塞讀。
  • 寫-寫互斥:寫寫阻塞

    果在系統中,讀操作的次數遠遠大于寫操作的次數,則讀寫鎖就可以發揮最大的功效,提升系統的性能。

2:ReadWriteLock讀寫鎖示範

我們來模拟在緩存(MyCache)中進行讀,寫分離操作示範

不使用ReadWriteLock的情況示範

class MyCache{
  private volatile HashMap<String,String> hashMap= new HashMap();
  public  void put(String key,String value) throws InterruptedException {
      System.out.println(Thread.currentThread().getName()+"----寫入資料");
      TimeUnit.MICROSECONDS.sleep(300);
      hashMap.put(key,value);
      System.out.println(Thread.currentThread().getName()+"----寫入資料完成");
  }
    public  void get(String key) throws InterruptedException {
        System.out.println(Thread.currentThread().getName()+"讀取資料");
        TimeUnit.MICROSECONDS.sleep(300);
        hashMap.get(key);
        System.out.println(Thread.currentThread().getName()+"讀取資料完成");
    }
}
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        for (int i=0;i<5;i++){
            final  int inttempt=1;
            new Thread(()->{
                try {
                    myCache.put(inttempt+" ",inttempt+"");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
        for (int i=0;i<5;i++){
            final  int inttempt=1;
            new Thread(()->{
                try {
                    myCache.get(inttempt+" ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}
           
JUC——ReadWriteLock讀寫鎖1:ReadWriteLock讀寫鎖介紹2:ReadWriteLock讀寫鎖示範

使用ReadWriteLock的情況示範

class MyCache{
  private volatile HashMap<String,String> hashMap= new HashMap();
3  private ReadWriteLock readWriteLock= new ReentrantReadWriteLock();
  public  void put(String key,String value) throws InterruptedException {
5      readWriteLock.writeLock().lock();
      try{
          System.out.println(Thread.currentThread().getName()+"----寫入資料");
          TimeUnit.MICROSECONDS.sleep(300);
          hashMap.put(key,value);
          System.out.println(Thread.currentThread().getName()+"----寫入資料完成");
      }catch(Exception e){
         e.printStackTrace();
      }finally{
          readWriteLock.writeLock().unlock();
      }
  }
    public  void get(String key) throws InterruptedException {
16      readWriteLock.readLock().lock();
      try{
          System.out.println(Thread.currentThread().getName()+"讀取資料");
          TimeUnit.MICROSECONDS.sleep(300);
          hashMap.get(key);
          System.out.println(Thread.currentThread().getName()+"讀取資料完成");
      }catch(Exception e){
         e.printStackTrace();
      }finally{
          readWriteLock.readLock().unlock();
      }
    }
}
public class ReadWriteLockDemo {
    public static void main(String[] args) {

        MyCache myCache = new MyCache();

        for (int i=0;i<5;i++){
            final  int inttempt=1;
            new Thread(()->{
                try {
                    myCache.put(inttempt+" ",inttempt+"");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
        for (int i=0;i<5;i++){
            final  int inttempt=1;
            new Thread(()->{
                try {
                    myCache.get(inttempt+" ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}
           
JUC——ReadWriteLock讀寫鎖1:ReadWriteLock讀寫鎖介紹2:ReadWriteLock讀寫鎖示範
讀線程完全并行,而寫會阻塞讀。如果使用讀寫鎖這段程式2秒就可以結束,如果使用可重入鎖和内部鎖,整個程式執行時間将要到5秒左右