《黑马程序员》 读写锁之缓存系统

------- android培训java培训、期待与您交流! ----------
public class CachedDemo {
	/**
	 * 缓存系统 
	 *     既然是存的缓存系统里面存储的就不是一个对象
	 *     就是别人想要获取某个对象的时候,可以通过我们的缓存系统去进行查找
	 *     我们先查找当前的缓存系统中是否有这个对象
	 *     如果有就返回该对象。如果没有就查找数据库
	 */
	//把对象存储在map集合中
	private Map<String,Object> map=new HashMap<String,Object>();
	public static void main(String[] args) {
       
	}
	
	//现在我们来使用读写锁来改写代码
	private ReadWriteLock rwl=new ReentrantReadWriteLock();
	public synchronized Object getData(String key){ //别人是通过key来获取对象
		//一上来就上读锁
		rwl.readLock().lock(); //上读锁所有的线程都是可以读的。所以线程都可以到这里来
		Object obj=null;  //局部变量在使用的时候一定要先初始化
		try {
			obj = map.get(key);
			if (obj == null) {
				//如果有一个线程发现数据为空了的话。就把读锁释放掉。要填充数据
				rwl.readLock().unlock();
				//上写锁开始写数据
				rwl.writeLock().lock();  //这样其它的线程都被堵在外面了
				try{
				    if(obj==null){
				    	obj = "query db"; //实际上是我们在这里就要去数据库中进行查找了
				    }
				}catch(Exception e){
					e.printStackTrace();
				}finally{
					//数据填充完之后把写锁给释放掉
					rwl.writeLock().unlock();
					//把读锁恢复
					rwl.readLock().lock();
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
		}finally{
			rwl.readLock().unlock();  //全部读完之后把读锁给释放掉
		}
		return obj; //这样下次再来查找的时候,如果数据是存在的就不用再查找数据库而是直接返回该数据了
	}
	//要让多个线程访问的时候产生互斥要使用synchronized将这个方法进行互斥
	
/*	我们在上面的时候发现了一个问题,如果有三个线程,它们都进来了。第一个线程发现数据为空,把锁给释放掉了
	其它的线程把就把锁都给释放掉了。然后它上了写锁,这样其它的线程是堵在外面的,它在填充完数据之后,把写锁给
	释放掉了,然后恢复了读锁的状态。第一个线程执行完之后,第二个线程,他也判断数据为空,它也进来了。它把读锁给释放掉了
	然后也也了写锁,然后给对象重复的赋值了。所以我们为了避免这类情况的发生。在对象填充数据的语句外面再进行一次判断。
	即线程是在上了写锁之后,如果数据为空的时候,才填充数据。不为空则不填充。
	这项是来自于:
	class CachedData {
		   Object data;
		   volatile boolean cacheValid;
		   ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

		   void processCachedData() {
		     rwl.readLock().lock();
		     if (!cacheValid) {
		        // Must release read lock before acquiring write lock
		        rwl.readLock().unlock();
		        rwl.writeLock().lock();
		        // Recheck state because another thread might have acquired
		        //   write lock and changed state before we did.
		        if (!cacheValid) {
		          data = ...
		          cacheValid = true;
		        }
		        // Downgrade by acquiring read lock before releasing write lock
		        rwl.readLock().lock();
		        rwl.writeLock().unlock(); // Unlock write, still hold read
		     }

		     use(data);
		     rwl.readLock().unlock();
		   }
		 }*/
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值