码迷,mamicode.com
首页 > 编程语言 > 详细

java中的读/写锁

时间:2018-03-14 20:45:45      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:取数   nbsp   import   实现   模拟   blocking   dwr   get   ant   

读写锁接口:ReadWriteLock,它的具体实现类为:ReentrantReadWriteLock

使用场景:

对于一个资源,读读能共存,读写不能共存,写写不能共存。

 

锁降级:从写锁变成读锁;

 

锁升级:从读锁变成写锁。

 

ReentrantReadWriteLock不支持锁升级,支持锁降级

 

ReadWriteLock rtLock = new ReentrantReadWriteLock();
 rtLock.readLock().lock();
 System.out.println("get readLock.");
 rtLock.writeLock().lock();
 System.out.println("blocking");

 

会死锁

ReadWriteLock rtLock = new ReentrantReadWriteLock();
rtLock.writeLock().lock();
System.out.println("writeLock");

rtLock.readLock().lock();
System.out.println("get read lock");

不会死锁

案例应用:

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

public class CacheDemo {
    /**
     * 缓存器,这里假设需要存储1000左右个缓存对象,按照默认的负载因子0.75,则容量=750,大概估计每一个节点链表长度为5个
     * 那么数组长度大概为:150,又有雨设置map大小一般为2的指数,则最近的数字为:128
     */
    private Map<String, Object> map = new HashMap<>(128);
    private ReadWriteLock rwl = new ReentrantReadWriteLock();
    public static void main(String[] args) {

    }
    public Object get(String id){
        Object value = null;
        rwl.readLock().lock();//首先开启读锁,从缓存中去取
        try{
            value = map.get(id);
            if(value == null){  //如果缓存中没有释放读锁,上写锁
                rwl.readLock().unlock();
                rwl.writeLock().lock();
                try{
                    if(value == null){ //防止多写线程重复查询赋值
                        value = "redis-value";  //此时可以去数据库中查找,这里简单的模拟一下
                    }
                    rwl.readLock().lock(); //加读锁降级写锁,不明白的可以查看上面锁降级的原理与保持读取数据原子性的讲解
                }finally{
                    rwl.writeLock().unlock(); //释放写锁
                }
            }
        }finally{
            rwl.readLock().unlock(); //最后释放读锁
        }
        return value;
    }
}

如果不使用锁降级功能,如先释放写锁,然后获得读锁,在这个get过程中,可能会有其他线程竞争到写锁 或者是更新数据 则获得的数据是其他线程更新的数据,可能会造成数据的污染,即产生脏读的问题。

 

java中的读/写锁

标签:取数   nbsp   import   实现   模拟   blocking   dwr   get   ant   

原文地址:https://www.cnblogs.com/L-a-u-r-a/p/8569749.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!