Skip to content
DAILY QUOTE

“ ”

ReadWriteLock

未加读写锁之前

java
package com.mystpet.ReadWriteLockTest;  
  
import java.util.HashMap;  
import java.util.Map;  
import java.util.concurrent.ConcurrentHashMap;  
  
public class ReadWriteLockDemo {  
    public static void main(String[] args) {  
        MyCache myCache = new MyCache();  
  
        //写入    
for (int i = 0; i < 6; i++) {  
            final int temp = i;  
            new Thread(()->{  
                myCache.put(temp+"",temp+"");  
            },String.valueOf(i)).start();  
        }  
  
        // 读取  
        for (int i = 1; i <= 5 ; i++ ) {  
            final int temp = i;  
            new Thread(() -> {  
                myCache.get(temp + "");  
            }, String.valueOf(i)).start();  
        }  
    }  
}  
  
//自定义缓存  class MyCache{  
    // volatile 保证内存可见性    
private volatile Map<String, Object> map = new HashMap<>();  
  
    // 存,写    
public void put(String key, Object value) {  
        System.out.println(Thread.currentThread().getName() + "写入" + key);  
        map.put(key, value);  
        System.out.println(Thread.currentThread().getName() + "写入完毕");  
    }  
  
    // 取,读    
public void get(String key) {  
        System.out.println(Thread.currentThread().getName() + "读取" + key);  
        Object o = map.get(key);  
        System.out.println(Thread.currentThread().getName() + "读取完毕");  
    }  
}

运行结果:发现写入的时候被插队了

加上读写锁后

java
/** * 独占锁、排它锁(写锁):一次只能被一个线程占有 
* 共享锁(读锁):多个线程可以同时占有 
* ReadWriteLock 
* 读-读 可以共存!
* 读-写 不能共存! 
* 写-写 不能共存! 
*/

package com.mystpet.ReadWriteLockTest;  
  
import java.util.HashMap;  
import java.util.Map;  
import java.util.concurrent.ConcurrentHashMap;  
import java.util.concurrent.locks.ReadWriteLock;  
import java.util.concurrent.locks.ReentrantReadWriteLock;  
  
public class ReadWriteLockDemo {  
    public static void main(String[] args) {  
        MyCacheLock myCache = new MyCacheLock();  
  
        //写入    
for (int i = 0; i < 6; i++) {  
            final int temp = i;  
            new Thread(()->{  
                myCache.put(temp+"",temp+"");  
            },String.valueOf(i)).start();  
        }  
  
        // 读取  
        for (int i = 1; i <= 5 ; i++ ) {  
            final int temp = i;  
            new Thread(() -> {  
                myCache.get(temp + "");  
            }, String.valueOf(i)).start();  
        }  
    }  
}  
  
//自定义缓存  class MyCacheLock {  
  
    // volatile 保证内存可见性  
    private volatile Map<String, Object> map = new HashMap<>();  
    // 读写锁:更加细粒度的控制  
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();  
  
    // 存,写入的时候,只希望只能有一个线程写  
    public void put(String key, Object value) {  
        readWriteLock.writeLock().lock();  
        try {  
            System.out.println(Thread.currentThread().getName() + "写入" + key);  
            map.put(key, value);  
            System.out.println(Thread.currentThread().getName() + "写入完毕");  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            readWriteLock.writeLock().unlock();  
        }  
    }  
  
    // 取,读,所有人都可以读  
    // 必须加读锁,为了是防止在写的时候进行读操作,会造成脏读现象  
    public void get(String key) {  
        readWriteLock.readLock().lock();  
        try {  
            System.out.println(Thread.currentThread().getName() + "读取" + key);  
            Object o = map.get(key);  
            System.out.println(Thread.currentThread().getName() + "读取完毕");  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            readWriteLock.readLock().unlock();  
        }  
    }  
}

结果:不会存在插队

要点:

  • 独占锁、排它锁(写锁):一次只能被一个线程占有
  • 共享锁(读锁):多个线程可以同时占有
  • ReadWriteLock
  • 读-读 可以共存!
  • 读-写 不能共存!
  • 写-写 不能共存!