用synchronized或者读写锁ReadWriteLock实现缓存机制《十一》

版权声明:本文为HCG原创文章,未经博主允许不得转载。请联系[email protected] https://blog.csdn.net/qq_39455116/article/details/86650037

用锁降级或者synchronized实现一个缓存

参考了很多网上的代码,发现大部分都是一模一样的,而且是错的,根本没有实现缓存
自己找了很久,发现了他们分别对应的问题A和B

// syn实现缓存里面最关键的步骤
 synchronized (map) {
                value = map.get(key);// A   这一行不能少
                if (value == null) {
                    value = "abc"; 
        if (value == null) {
                try {
                    rwl.readLock().unlock();//关闭读锁
                    rwl.writeLock().lock();//开启写锁
                    // B   这个地方需要再检查一下,不检查的话,这个缓存就实现不了
                    value = map.get(key);

代码如下:

package duoxiancheng.reentrantLock.read;

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

public class CacheMap {

    //声明一个map,用来作为缓存模型
    private static Map<String, Object> map = new HashMap<String, Object>();
    //声明一个读写锁
    private static ReadWriteLock rwl = new ReentrantReadWriteLock();


   //用synchronized关键字实现一个缓存
    public Object synGetValue(String key) {
        Object value = map.get(key);
        if (value == null) {
            synchronized (map) {
                value = map.get(key); //  A
                if (value == null) {
                    value = "abc";//这里是去数据库查询
                    map.put(key, value);//将数据放到缓存模型中
                    System.out.println(Thread.currentThread().getName() + "syn方式实现,put也只执行一次");
                }
            }
        }
        return value;
    }
    
    
   //用读写锁的锁降级实现一个缓存
    public Object getValue(String key) {
        Object value = null;
        try {
            rwl.readLock().lock();//开启读锁
            value = map.get(key);
            if (value == null) {
                try {
                    rwl.readLock().unlock();//关闭读锁
                    rwl.writeLock().lock();//开启写锁
                    //这个地方需要再检查一下,不检查的话,这个缓存就实现不了
                    value = map.get(key); //B
                    if (value == null) {
                        value = "abc";//这里是去数据库查询
                        map.put(key, value);//将数据放到缓存模型中
                        System.out.println(Thread.currentThread().getName() + "=======这个只执行一次=========");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    rwl.writeLock().unlock();//关闭写锁
                    rwl.readLock().lock();//开启读锁
                    //System.out.println(Thread.currentThread().getName() + "----2----");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            rwl.readLock().unlock();//关闭读锁
            //System.out.println(Thread.currentThread().getName() + "----3----");
        }
        return value;

    }


    public static void main(String[] args) {
        CacheMap cacheMap = new CacheMap();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + cacheMap.getValue("readWrite"));

            }, "--------readWrite线程" + i).start();

            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + cacheMap.synGetValue("syn"));

            }, "synchronized线程" + i).start();
        }
    }
}

9. 结果分析
--------readWrite线程0=======这个只执行一次=========
--------readWrite线程0abc
synchronized线程0syn方式实现,put也只执行一次
synchronized线程0abc
synchronized线程1abc
--------readWrite线程1abc
synchronized线程2abc
--------readWrite线程2abc
--------readWrite线程3abc
synchronized线程3abc
synchronized线程4abc
--------readWrite线程5abc
--------readWrite线程4abc
--------readWrite线程6abc
synchronized线程6abc
--------readWrite线程7abc
synchronized线程5abc
--------readWrite线程8abc
synchronized线程7abc
--------readWrite线程9abc
synchronized线程8abc
synchronized线程9abc
发现满足了线程安全的定义,只有一个线程往其中put了数据,实现了缓存
但是其实如果只是缓存的存的话,用synchronized会更简单一些,效率两个都差不多

猜你喜欢

转载自blog.csdn.net/qq_39455116/article/details/86650037