zoukankan      html  css  js  c++  java
  • JAVA 并发编程-读写锁之模拟缓存系统(十一)

       

        在多线程中,为了提高效率有些共享资源同意同一时候进行多个读的操作,但仅仅同意一个写的操作,比方一个文件,仅仅要其内容不变能够让多个线程同一时候读,不必做排他的锁定,排他的锁定仅仅有在写的时候须要,以保证别的线程不会看到数据不完整的文件。这时候就须要使用读写锁。


    /**
     * 简单读写锁demo
     * @author hejingyuan
     *
     */
    public class ReadWriteLockTest {
    	public static void main(String[] args) {
    		final Queue3 q3 = new Queue3();
    		//创建几个线程
    		for(int i=0;i<3;i++)
    		{
    			new Thread(){
    				public void run(){
    					while(true){
    						q3.get();						
    					}
    				}
    				
    			}.start();
    			
    			new Thread(){
    				public void run(){
    					while(true){
    						q3.put(new Random().nextInt(10000));
    					}
    				}			
    				
    			}.start();
    			
    		}
    		
    	}
    }
    
    class Queue3{
    	private Object data = null;//共享数据。仅仅能有一个线程能写该数据,但能够有多个线程同一时候读该数据
    	//读写锁
    	ReadWriteLock rwl = new ReentrantReadWriteLock();
    	//读数据
    	public void get(){
    		rwl.readLock().lock();
    		try {
    			System.out.println(Thread.currentThread().getName() + " be ready to read data!");
    			Thread.sleep((long)(Math.random()*1000));
    			System.out.println(Thread.currentThread().getName() + "have read data :" + data);			
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}finally{
    			rwl.readLock().unlock();
    		}
    	}
    	//写数据
    	public void put(Object data){
    
    		rwl.writeLock().lock();
    		try {
    			System.out.println(Thread.currentThread().getName() + " be ready to write data!");					
    			Thread.sleep((long)(Math.random()*1000));
    			this.data = data;		
    			System.out.println(Thread.currentThread().getName() + " have write data: " + data);					
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}finally{
    			rwl.writeLock().unlock();
    		}
    		
    	
    	}
    }
    


    运行结果:

     

    Thread-0 be ready to readdata!

    Thread-2 be ready to readdata!

    Thread-2have read data:null

    Thread-0have read data:null

    Thread-1 be ready towrite data!

    Thread-1 have write data:1021

    Thread-1 be ready towrite data!

    Thread-1 have write data:2887

     

    看到这里不免有人会问。既然读的时候能够多人訪问。那么为什么还要加读锁呢?

    答:当然要加锁了,否则在写时去读,可能不对-(写的时候不能去读)

     

    读写锁-模拟缓存系统实现:


    public class CacheDemo {
    
    	private Map<String, Object> cache = new HashMap<String, Object>();
    	public static void main(String[] args) {
    		
    
    	}
    
    	//定义读写锁
    	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();
    				//加上写锁
    				rwl.writeLock().lock();
    				try{
    					//如果三个线程同一时候去获取写锁,我们知道仅仅有第一个线程能够获取
                        //那么其它两个线程仅仅有等了,如果第一个线程按流程运行完后,刚才的两个线程能够得到写锁了,
                        //然后接着就能够改动数据了(赋值).所以加上推断!
    					if(value==null){//为什么还要推断?
    						value = "aaaa";//实际是去queryDB();
    					}
    				}finally{
    					//释放写锁
    					rwl.writeLock().unlock();
    				}
    				rwl.readLock().lock();
    			}
    		}finally{
    			rwl.readLock().unlock();
    		}
    		return value;
    	}
    }
    


    总结:

     

        读写锁的作用为,当我们加上写锁时,其它线程被堵塞,仅仅有一个写操作在运行,当我们加上读锁后,它是不会限制多个读线程去訪问的。也就是getput之间是相互排斥的。put与不论什么线程均为相互排斥。可是getget线程间并非相互排斥的。事实上加读写锁的目的是同一把锁的读锁既能够与写锁相互排斥,读锁之间还能够共享。




  • 相关阅读:
    学习增删查改
    学习MVC
    Milkyway 用的不规则LEF
    innovus 自学之 摆放数模接口port
    innovus 自学之 一些小命令
    innovus 自学小技巧之 gui小配置
    innovus 自学小技巧之floorplan
    第二周 第四节pyc是什么
    第二周 第三节初识模块2
    第二周第二节模块初识
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7146773.html
Copyright © 2011-2022 走看看