zoukankan      html  css  js  c++  java
  • 读写锁

    相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些。假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存)。这就需要一个读/写锁来解决这个问题。Java5在java.util.concurrent包中已经包含了读写锁。尽管如此,我们还是应该了解其实现背后的原理。

     读 写 这种的 可以用wait  notify 之前已经实现过了  读的时候不能写 写的时候不能做 保证共性的全局变量安全

    下面,先来写个读写锁大家看看:

    package com.toov5.readAndWriteLock;
    
    import java.util.HashMap;
    import java.util.Map;
    
    //读写锁 类似jvm内置缓存(把值存到jvm中)
    public class writeAndReadLock {
        private volatile Map<Object,Object> cache = new HashMap<>();  
        
        //写入元素
        public void put(String key,String value){
            try {
                Thread.sleep(500);
                System.out.println("写入"+key+value);
                cache.put(key, value);
                System.out.println("写入"+key+value+"结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        //读取元素
        public String get(String key){
            try {
                Thread.sleep(500);
                System.out.println("读取"+key);
                String result = cache.get(key).toString();
                System.out.println("读取"+key+"结束");
                return result;
            } catch (Exception e) {
                return null;
            }
        }
        
         public static void main(String[] args) {
            writeAndReadLock lock = new writeAndReadLock();
            //写线程
              Thread t1 = new Thread(new Runnable() {    
                @Override
                public void run() {
                    for(int i =0; i<10;i++){
                        lock.put("i", i+"");
                    }
                }
            });
              
          //读线程      
              Thread t2 = new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        for(int i=0; i<10;i++){
                            lock.get(i+"");
                        }
                    }
                }); 
          t1.start();
          t2.start();
              
        }
        
    }

    结果:

    如果两个方法都加上synchronize 那么读的时候 不能写 写的时候不能读

    下面提供读写锁:

    package com.toov5.readAndWriteLock;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
    
    //读写锁 类似jvm内置缓存(把值存到jvm中)
    public class writeAndReadLock {
        private volatile Map<Object,Object> cache = new HashMap<>();  
        private ReentrantReadWriteLock wrl = new ReentrantReadWriteLock();  
        private WriteLock wirtelock=wrl.writeLock();//获取到写锁
        private ReadLock readLock =wrl.readLock(); //获取到读锁
        //写入元素
        public void put(String key,String value){
            try {    
                wirtelock.lock();
                Thread.sleep(500);
                System.out.println("写入"+key+value);
                cache.put(key, value);
                System.out.println("写入"+key+value+"结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                wirtelock.unlock();
            }
        }
        
        //读取元素
        public String get(String key){
            try {
                readLock.lock();
                Thread.sleep(500);
                System.out.println("读取"+key);
                String result = cache.get(key).toString();
                System.out.println("读取"+key+"结束");
                return result;
            } catch (Exception e) {
                return null;
            }finally{
                readLock.unlock();
            }
        }
        
         public static void main(String[] args) {
            writeAndReadLock lock = new writeAndReadLock();
            //写线程
              Thread t1 = new Thread(new Runnable() {    
                @Override
                public void run() {
                    for(int i =0; i<10;i++){
                        lock.put("i", i+"");
                    }
                }
            });
              
          //读线程      
              Thread t2 = new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        for(int i=0; i<10;i++){
                            lock.get(i+"");
                        }
                    }
                }); 
          t1.start();
          t2.start();
              
        }
        
    }

    没有写完时候 是不能读的

    看源码:

    与之前的lock锁不一样之前是 reentrantlock,它有读和写两把锁

     两个线程同时写,同时读是不可能的。不共存! 

    读读 可以 读写不可共存  写写不可以共存

  • 相关阅读:
    SpringBoot(三) 配置文件 篇章
    SpringBoot(二):SpringBoot 热部署
    SSM框架之Spring(2)IOC及依赖注入
    SSM框架之spring(1)
    SSM框架之Mybatis(6)动态SQL
    SSM框架之Mybatis(5)数据库连接池及事务
    SSM框架之Mybatis(4)SqlMapConfig
    SSM框架之Mybatis(3)dao层开发
    SSM框架之Mybatis(2)CRUD操作
    JavaEE之Hibernate(开放源代码的对象关系映射框架)
  • 原文地址:https://www.cnblogs.com/toov5/p/9857334.html
Copyright © 2011-2022 走看看