我爱编程

java-读写锁

2018-04-15  本文已影响34人  萤火之森ss

特点:在读写锁中,读锁是允许多个线程同时访问的,但是在写锁访问的时候其他企图访问读锁和写锁都是被阻塞的。

历史:在jdk5之前,假如有场景:大部分都是读的场景,写的场景很少,但是写之后的数据要对所有的读所见。

java中的读写锁是RenntrantReadWriteLock,它具有如下特点,公平性选择,重入,降级锁,但是没有升级锁。
RenntrantReadWriteLock内部的一些工具方法:
int getReadLockCount():返回当前读锁被获取的次数,总次数和线程数没关系
int getReadHoldCount():返回当前线程获取读锁的次数,
boolean isWriteLockd():判断写锁是否被获取
int getWriteHoldCont():返回当前线程获取写锁的次数

实例:

public class lock {


    static Map<String,Object> map = new HashMap<>();
    static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    //读锁
    static Lock r = rwl.readLock();
    //写锁
    static Lock w = rwl.writeLock();

    public static final Object get(String key){

        r.lock();
        try {
            return map.get(key);
        }finally {
            r.unlock();
        }


    }

    public static final Object put(String key,Object value){

        w.lock();
        try {
            return map.put(key,value);
        }finally {
            w.unlock();
        }
    }

    public static final void clear(){

        w.lock();
        try {
            map.clear();
        }finally {
            w.unlock();
        }
    }
}

写锁是一个重入的过程,再次获得增加写锁的状态。
如果当前线程获取写锁的时候,读锁已经被其他线程获取,则当前线程进入等待状态。
ReentrantReadWriteLock的tryAcquire方法:

protected final boolean tryAcquir(int acquire){
  Thread current = Thread.currentThread();
  //获取同步状态值 0代表没有被持有
  int  c = getState();
  //获取写状态 
  int w = exclusiveCount(c);
  if(c!=0){
    //读锁被占有了,或者持有锁线程不是当前线程
    if(w == 0 || current !=getExclusiveOwnerThread()){
      return false;
    }
    //大于最大值
    if(w + exclusiveCount(acquires) > MAX_COUNT)
      throw ...
    //否则增加状态,这里是当前线程重入了
    setState(c);
    return true;
  //
  if(writeShouldBolck() || !compareAndSetState(c,c+acquires)){
    return false;  
  }
  //当前线程获得锁
  setExclusiverOwnerThread(current);
  return ture;
}
上一篇 下一篇

猜你喜欢

热点阅读