zoukankan      html  css  js  c++  java
  • 多线程之ReadWriteLock模拟缓存(九)

    错误案例1:

    package com.net.thread.lock;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /**
     * @author 
     * @Time:2017年8月23日 下午6:09:20
     * @version 1.0
     * @description 读写锁模拟缓存技术 ,错误写法1
     */
    public class Example
    {
        public static void main(String[] args)
        {
            Demo demo = new Demo();
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    System.out.println(demo.get("java"));
                }
            }).start();
    
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    System.out.println(demo.get("java"));
                }
            }).start();
        }
    
        static class Demo
        {
            ReadWriteLock rwl = new ReentrantReadWriteLock();
            Map<Object, Object> map = new HashMap<Object, Object>();
            boolean flag;
            
            public Object get(Object key)
            {
                rwl.readLock().lock();
    
                Object value = null;
                value = map.get(key);
                
                //if不安全,如果在这里边的value依旧是null,则根本没有安全保障                
                if (value == null) {
                    flag = false;
                    rwl.readLock().unlock();
                    rwl.writeLock().lock();
                    System.out.println(Thread.currentThread().getName() + " 的flag:" + flag);
                    if (!flag) {
                        value =  null;
                        map.put(key, value);
                        flag = true;
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    rwl.writeLock().unlock();
                    rwl.readLock().lock();
                }
    
                rwl.readLock().unlock();
                return value;
            }
        }
    
    }

    错误案例2: 在前一个案例中进行改造,但不完全;此例子中的flag是局部变量,而局部变量实际上是线程安全,就相当于每个线程开始都有一个flag=false的结果,因此,多次调用,多次初始化,并没有起到缓存的作用

    package com.net.thread.lock;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /**
     * @author 
     * @Time:2017年8月23日 下午6:09:20
     * @version 1.0
     * @description 读写锁模拟缓存技术,错误写法2
     */
    public class Example2
    {
        public static void main(String[] args)
        {
            Demo demo = new Demo();
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    System.out.println(demo.get("java"));
                }
            }).start();
    
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    System.out.println(demo.get("java"));
                }
            }).start();
        }
    
        static class Demo
        {
            ReadWriteLock rwl = new ReentrantReadWriteLock();
            Map<Object, Object> map = new HashMap<Object, Object>();
            int i = 1;
            
            public Object get(Object key)
            {
                boolean flag = false;
                rwl.readLock().lock();
                Object value = map.get(key);
                while (value == null) 
                {
                    System.out.println(Thread.currentThread().getName() + " 的flag:" + flag);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    rwl.readLock().unlock();
                    rwl.writeLock().lock();
                    if (!flag) 
                    {
                        map.put(key, "初始化");
                        flag = true;
                        System.out.println(Thread.currentThread().getName() + "写完后的flag :" + flag + " 次数:" + i);
                        i++;
                    }
                    rwl.writeLock().unlock();
                    rwl.readLock().lock();
                    value = map.get(key);
                }
                
                rwl.readLock().unlock();
                return value;
            }
        }
    }

    正确写法:

    package com.net.thread.lock;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /**
     * @author 
     * @Time:2017年8月23日 下午6:09:20
     * @version 1.0
     * @description 读写锁模拟缓存技术,正确写法
     */
    public class Example3
    {
        public static void main(String[] args)
        {
            Demo demo = new Demo();
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    System.out.println(demo.get("java"));
                }
            }).start();
    
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    System.out.println(demo.get("java"));
                }
            }).start();
        }
    
        static class Demo
        {
            ReadWriteLock rwl = new ReentrantReadWriteLock();
            Map<Object, Object> map = new HashMap<Object, Object>();
            int i = 1;
            boolean flag = false;
            
            public Object get(Object key)
            {
                rwl.readLock().lock();
                Object value = map.get(key);
                while (value == null) 
                {
                    System.out.println(Thread.currentThread().getName() + " 的flag:" + flag);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    rwl.readLock().unlock();
                    rwl.writeLock().lock();
                    if (!flag) 
                    {
                        map.put(key, "初始化");
                        flag = true;
                        System.out.println(Thread.currentThread().getName() + "写完后的flag :" + flag + " 次数:" + i);
                        i++;
                    }
                    rwl.writeLock().unlock();
                    rwl.readLock().lock();
                    value = map.get(key);
                }
                
                rwl.readLock().unlock();
                return value;
            }
        }
    }
  • 相关阅读:
    很漂亮的按钮css样式(没有用到图片,可直接拷贝代码使用)
    if、while中变量的作用域问题
    笔记
    搭建高可用mongodb集群(一)——配置mongodb
    Java编程:删除 List 元素的三种正确方法
    MySQL 数据类型
    MySQL 通用查询日志(General Query Log)
    mysql 创建一个用户,指定一个数据库
    MySQL 5.7 免安装版配置
    String,StringBuffer与StringBuilder的区别??
  • 原文地址:https://www.cnblogs.com/chen1-kerr/p/7421505.html
Copyright © 2011-2022 走看看