Read and write lock ReentrantReadWriteLock learning

1. Ideas

1. Open the read lock first to get the cached data value

2. Judge the value, if it is empty, close the read lock; open the write lock, and get the cache data value (other threads may assign values), if the value is empty, assign a value to the cache. And downgrade the write lock to a read lock.

3. If it is not empty, get the value and close the read lock.

Note : Whether the key of the read-write lock has a cache value, what operations are performed, and what operations are not performed. This process must consider other thread assignment issues, and then perform the corresponding operations.

Second, the code example

// 读写锁
public static void ReentrantReadWriteLockCacheSystem() {

    //这里为了实现简单,将缓存大小设置为4。
    Map<String, String> cacheMap = new HashMap<>(4);
    ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    for (int i = 0; i < 20; i++) { //同时开启20个线程访问缓存

        final String key = String.valueOf(i % 4);
        log.info(Thread.currentThread().getName()+"key:{}",key);
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    //①读取缓存时获取读锁
                    readWriteLock.readLock().lock();
                    //获取读锁后通过key获取缓存中的值
                    String valueStr = cacheMap.get(key);
                    log.info("value:{}",valueStr);
                    //缓存值不存在
                    if (valueStr == null) {
                        //③释放读锁后再尝试获取写锁
                        // 读不到数据,就关闭读锁,开启写锁
                        readWriteLock.readLock().unlock();  //关闭读锁
                        try {
                            //④获取写锁来写入不存在的key值,
                            readWriteLock.writeLock().lock();
                            valueStr = cacheMap.get(key);
                            log.info("key:{}"+key+",关闭读锁后value:{}",valueStr);
                            if (valueStr == null) {
                                valueStr = key + " --- value";
                                log.info("为锁赋值:{}",valueStr);
                                cacheMap.put(key, valueStr); //写入值
                                System.out.println(Thread.currentThread().getName() + " --------- put " + valueStr);
                            }
                            // ⑥锁降级,避免被其他写线程抢占后再次更新值,保证这一次操作的原子性
                            readWriteLock.readLock().lock();
                            log.info("读锁操作:{}"+key);
                            System.out.println(Thread.currentThread().getName() + " --------- get new " + valueStr);
                        } finally {
                            log.info("写锁操作:{}",key);
                            readWriteLock.writeLock().unlock(); //⑤释放写锁
                        }

                    } else {
                        System.out.println(Thread.currentThread().getName() + " ------ get cache value");
                    }
                } finally {
                    log.info("释放读锁:{}",key);
                    readWriteLock.readLock().unlock();  //②释放读锁
                }
            }
        }, String.valueOf(i));
        thread.start();
    }
}

Third, the technology involved

   1, lombok, multi-threaded read and write class ReentrantReadWriteLock

    2. Project demo. https://github.com/krycai/MultiThread's   class LockDemo2

Guess you like

Origin blog.csdn.net/baidu_28068985/article/details/103898229