zoukankan      html  css  js  c++  java
  • JAVA线程锁-读写锁应用,简单的缓存系统

    在JAVA1.5版本以后,JAVA API中提供了ReadWriteLock,此类是一个接口,在它的实现类中ReentrantReadWriteLock中有这样一段代码

    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();
       }
     }

    以上代码是一个简单的缓存实现方式,根据以上思路写出如下代码

    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class CacheSystemTest {
    
        private Map<String, Object> cacheMap = new HashMap<String, Object>();
        
        private ReadWriteLock rwl = new ReentrantReadWriteLock();
        
        /**
         * 为了防止在多线程情景下数据安全问题,需要线程互斥,实现方式是用锁
         * @param key
         * @return
         */
        public Object get(String key){
            rwl.readLock().lock();    //任何一个线程进来后,第一时间加上读锁
            Object obj = null; 
            try{
                obj = cacheMap.get(key);
                if(obj == null){
                    rwl.readLock().unlock();    //在赋值前关闭读锁,并在此检查对象
                    if(obj == null){
                        rwl.writeLock().lock();    //打开一个写锁
                        try{
                            obj = "read write lock";
                        }finally{
                            rwl.writeLock().unlock();    //关闭写锁
                            rwl.readLock().lock();    //恢复正常读锁
                        }
                    }
                }
            }finally{
                rwl.readLock().unlock();
            }
            return obj;
        }
    }

     注:此锁最多支持65535个递归写入锁和读锁,如果试图超出则抛出Error错误

  • 相关阅读:
    jdbctemplate的batchUpdate使用方法
    js利用html5的canvas实现图像等比例压缩
    js前台通过EXIF.js获取图片中携带的经纬度信息
    Linux expr相关
    expect用于scp传输文件
    linux 自动登录ftp 获取文件
    作业8:单元测试练习(个人练习)
    作业7-用户体验设计案例分析
    作业6:团队作业——学生成绩录入系统设计与实现
    作业5:需求分析
  • 原文地址:https://www.cnblogs.com/duwenlei/p/5110325.html
Copyright © 2011-2022 走看看