zoukankan      html  css  js  c++  java
  • 多线程12_张孝祥 java5读写锁技术的妙用

    package locks;
    
    import java.util.Random;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /* 
     *ReentrantReadWriteLock  读写互斥,
     *如果读操作被上锁,写操作就不能进行,
     *如果写操作被上锁,读操作就不能进行,
     *
     *读操作上锁后,需要解锁后, 写才能上锁。
     * 如果读没有解锁,还调用了写的锁,就会造成堵塞,让线程卡在哪里。
     * 反之却是可以的,即在写没有解锁,读操作上锁是可以的。(叫做降级锁)
     * 
     */
    public class ReadWriteLockTest {
    
        public static void main(String[] args) {
            final Queue q3 = new Queue();
            // 弄3个读的线程, 弄3个写的线程
            for (int i = 1; i <= 3; i++) {
                new Thread() {
                    public void run() {
                        while (true) {
                            q3.put(new Random().nextInt(10000));
                        }
                    }
                }.start();
    
                new Thread() {
                    public void run() {
                        while (true) {
                            q3.get();
                        }
                    }
                }.start();
            }
        }
    }
    
    class Queue {
        private Object data = null;
        // hibernate load的方法实现就是 ReentrantReadWriteLock 放在代理对象中
        private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    
        public void get() {
            rwl.readLock().lock();
            try {
                System.out.println(Thread.currentThread().getName() + "开始取");
                Thread.sleep((long) (Math.random() * 1000));
                System.out.println(Thread.currentThread().getName() + "取完毕" + data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            rwl.readLock().unlock();
        }
    
        public void put(Object obj) {
            rwl.writeLock().lock();
            try {
                System.out.println(Thread.currentThread().getName() + "开始写");
                Thread.sleep((long) (Math.random() * 1000));
                this.data = obj;
                System.out.println(Thread.currentThread().getName() + "写结束" + obj);
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            rwl.writeLock().unlock();
        }
    }

    执行结果:

    Thread-1开始取
    Thread-1取完毕null
    Thread-0开始写
    Thread-0写结束4973
    Thread-4开始写
    Thread-4写结束2476
    Thread-3开始取
    Thread-3取完毕2476
    Thread-2开始写
    Thread-2写结束3388
    Thread-2开始写
    Thread-2写结束2905
    Thread-5开始取
    Thread-1开始取
    Thread-1取完毕2905
    Thread-5取完毕2905
    Thread-0开始写
    Thread-0写结束4504
    Thread-4开始写
    Thread-4写结束9962
    Thread-3开始取
    Thread-3取完毕9962
    Thread-2开始写
    Thread-2写结束3281
    Thread-2开始写
    Thread-2写结束1530
    Thread-1开始取
    Thread-5开始取
    Thread-5取完毕1530
    Thread-1取完毕1530
    Thread-0开始写
    Thread-0写结束8294
    Thread-0开始写
    Thread-0写结束7573
    Thread-4开始写
    Thread-4写结束4506
    Thread-4开始写
    Thread-4写结束4768
    Thread-3开始取
    Thread-3取完毕4768
    Thread-2开始写

    package concurrent;
    
    import java.util.HashMap;
    import java.util.Map;
    /**
     *缓存的实现思路
     */
    public class CacheDemo {
    
        private Map<String, Object> cache=new HashMap<String, Object>();
        public static void main(String[] args) {
            
        }
        
        //同步取数据
        public synchronized Object getData(String key){
            Object value=cache.get(key);
            
            if(value==null){
                value="aaaa";//实际是去queryDB()   查询数据库
            }
            return value;
        }
    }

    缓存的思路

    通过锁实现思路

    package concurrent;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    /**
     *缓存系统的实现思路
     *
     */
    public class CacheDemo2 {
    
        private Map<String, Object> cache=new HashMap<String, Object>();
        private ReadWriteLock rwl=new ReentrantReadWriteLock();
        public Object getData(String key){
            
            rwl.readLock().lock();
            Object value=null;
            try {
                value = cache.get(key);
                if(value==null){
                    rwl.readLock().unlock();//1 、这里不解读锁,  后面调用写锁直接进入死锁状态。
                    rwl.writeLock().lock();
                    try {
                        if(value==null){
                             value="aaaa";//实际是去
                  queryDBcache.put(key, value);
    } } finally {
                rwl.readLock.lock(); //2、 在写锁内调用读锁是可以的,叫做降级锁。 rwl.writeLock().unlock(); } } }
    catch (Exception e) { e.printStackTrace(); }finally{ rwl.readLock().unlock(); } return value; } }
  • 相关阅读:
    经典假设检验理论记录一二
    阿里云centos7.3安装tomcat8
    PowerDesigner中Name与Code同步的问题
    PowerDesigner中NAME和COMMENT的互相转换
    树形结构的数据库表设计
    Spring mybatis Access denied for user 'root'@'localhost' (using password:YES)
    IOS上架审核问题
    maven自动部署war包到tomcat 问题
    SpringMVC +Hibernate JPA+Spring-data-jpa
    Hibernate4.3.x Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
  • 原文地址:https://www.cnblogs.com/laj12347/p/4404086.html
Copyright © 2011-2022 走看看