JAVA 并发编程-读写锁之模拟缓存系统(十一)
发布日期:2022-01-11 03:09:56 浏览次数:6 分类:技术文章

本文共 2560 字,大约阅读时间需要 8 分钟。

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

[java]
  1. /** 
  2.  * 简单读写锁demo 
  3.  * @author hejingyuan 
  4.  * 
  5.  */  
  6. public class ReadWriteLockTest {  
  7.     public static void main(String[] args) {  
  8.         final Queue3 q3 = new Queue3();  
  9.         //创建几个线程  
  10.         for(int i=0;i<3;i++)  
  11.         {  
  12.             new Thread(){  
  13.                 public void run(){  
  14.                     while(true){  
  15.                         q3.get();                         
  16.                     }  
  17.                 }  
  18.                   
  19.             }.start();  
  20.               
  21.             new Thread(){  
  22.                 public void run(){  
  23.                     while(true){  
  24.                         q3.put(new Random().nextInt(10000));  
  25.                     }  
  26.                 }             
  27.                   
  28.             }.start();  
  29.               
  30.         }  
  31.           
  32.     }  
  33. }  
  34.   
  35. class Queue3{  
  36.     private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据  
  37.     //读写锁  
  38.     ReadWriteLock rwl = new ReentrantReadWriteLock();  
  39.     //读数据  
  40.     public void get(){  
  41.         rwl.readLock().lock();  
  42.         try {  
  43.             System.out.println(Thread.currentThread().getName() + " be ready to read data!");  
  44.             Thread.sleep((long)(Math.random()*1000));  
  45.             System.out.println(Thread.currentThread().getName() + "have read data :" + data);             
  46.         } catch (InterruptedException e) {  
  47.             e.printStackTrace();  
  48.         }finally{  
  49.             rwl.readLock().unlock();  
  50.         }  
  51.     }  
  52.     //写数据  
  53.     public void put(Object data){  
  54.   
  55.         rwl.writeLock().lock();  
  56.         try {  
  57.             System.out.println(Thread.currentThread().getName() + " be ready to write data!");                    
  58.             Thread.sleep((long)(Math.random()*1000));  
  59.             this.data = data;         
  60.             System.out.println(Thread.currentThread().getName() + " have write data: " + data);                   
  61.         } catch (InterruptedException e) {  
  62.             e.printStackTrace();  
  63.         }finally{  
  64.             rwl.writeLock().unlock();  
  65.         }  
  66.           
  67.       
  68.     }  
  69. }  

运行结果:

 

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

 

看到这里不免有人会问,既然读的时候可以多人访问,那么为什么还要加读锁呢?

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

 

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

[java]
  1. public class CacheDemo {  
  2.   
  3.     private Map<String, Object> cache = new HashMap<String, Object>();  
  4.     public static void main(String[] args) {  
  5.           
  6.   
  7.     }  
  8.   
  9.     //定义读写锁  
  10.     private ReadWriteLock rwl = new ReentrantReadWriteLock();  
  11.     //读数据,使用读锁  
  12.     public  Object getData(String key){  
  13.         //添加读锁  
  14.         rwl.readLock().lock();  
  15.         Object value = null;  
  16.         try{  
  17.             value = cache.get(key);  
  18.             if(value == null){  
  19.                 //释放读锁  
  20.                 rwl.readLock().unlock();  
  21.                 //加上写锁  
  22.                 rwl.writeLock().lock();  
  23.                 try{  
  24.                     //假设三个线程同时去获取写锁,我们知道只有第一个线程能够获取  
  25.                     //那么其他两个线程只有等了,如果第一个线程按流程执行完后,刚才的两个线程可以得到写锁了,  
  26.                     //然后接着就可以修改数据了(赋值).所以加上判断!  
  27.                     if(value==null){
    //为什么还要判断?  
  28.                         value = "aaaa";//实际是去queryDB();  
  29.                     }  
  30.                 }finally{  
  31.                     //释放写锁  
  32.                     rwl.writeLock().unlock();  
  33.                 }  
  34.                 rwl.readLock().lock();  
  35.             }  
  36.         }finally{  
  37.             rwl.readLock().unlock();  
  38.         }  
  39.         return value;  
  40.     }  
  41. }  

总结:

 

    读写锁的作用为,当我们加上写锁时,其他线程被阻塞,只有一个写操作在执行,当我们加上读锁后,它是不会限制多个读线程去访问的。也就是getput之间是互斥的,put与任何线程均为互斥,但是getget线程间并不是互斥的。其实加读写锁的目的是同一把锁的读锁既可以与写锁互斥,读锁之间还可以共享。

转载地址:https://yuki-ho.blog.csdn.net/article/details/52316442 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:JAVA 并发编程-线程同步工具类(十二)
下一篇:JAVA 并发编程-线程同步通信技术(Lock和Condition)(十)

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年03月29日 20时53分12秒