当前位置:   article > 正文

读写锁ReadWriteLock

readwritelock

        在jdk帮助文档中是这么说的:A ReadWriteLock维护一对关联的locks,一个用于只读操作,一个用于写操作。read lock可以由多个阅读器同时进行,只要没有作者 write lock 是独家的

        意思就是读操作可以被多个线程同时读,写操作只能由一个线程去写

        ReadWriteLock同Lock一样也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个是只读的锁,一个是写锁。ReentranReadWriteLock是其实现类。

ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
  1. public interface ReadWriteLock {
  2. //返回读锁
  3. Lock readLock();
  4. //返回写锁
  5. Lock writeLock();
  6. }
  1. readWriteLock.writeLock().lock();
  2. readWriteLock.writeLock().unlock();
  3. readWriteLock.readLock().lock();
  4. readWriteLock.readLock().unlock();

         读写锁的使用场景:在一些共享资源的读和写操作,且写操作没有读操作那么频繁的场景下可以用读写锁。

互斥原则:

  1. - 读 ---> 可以共存(即可以用多个线程同时读取)
  2. - 写 ---> 不能共存(即读的时候不能有其他线程去修改或写入,修改或写入的时候不能有其他线程去读)
  3. - 写 ---> 不能共存(一个线程修改或写入的时候不能同时有其他线程写入或修改)

下面写一个不加锁的读写示例:

  1. public class ReadWriteLockDemo {
  2. public static void main(String[] args) {
  3. MyCache1 myCache = new MyCache1();
  4. //写入操做
  5. for (int i = 1; i <= 5; i++) {
  6. final String temp = i+" ";
  7. new Thread(()->{
  8. myCache.put(temp,temp);
  9. },String.valueOf(i)).start();
  10. }
  11. //读取操作
  12. for (int i = 1; i <= 5; i++) {
  13. final String temp = i+" ";
  14. new Thread(()->{
  15. myCache.get(temp);
  16. },String.valueOf(i)).start();
  17. }
  18. }
  19. }
  20. /*
  21. 自定义缓存
  22. */
  23. class MyCache1 {
  24. private volatile Map<String,Object> map = new HashMap<>();
  25. //存,写
  26. public void put(String key,Object value){
  27. System.out.println(Thread.currentThread().getName()+"写入"+key);
  28. map.put(key,value);
  29. System.out.println(Thread.currentThread().getName()+"写入成功"+key);
  30. }
  31. //取,读
  32. public void get(String key){
  33. System.out.println(Thread.currentThread().getName()+"读取"+key);
  34. Object o = map.get(key);
  35. System.out.println(Thread.currentThread().getName()+"读取成功"+o);
  36. }
  37. }

从运行结果可以看到,线程在执行写操作的时候,会存在被其他线程插队的现象。而加上读写锁就可以有效解决这一问题

  1. public class ReadWriteLockDemo {
  2. public static void main(String[] args) {
  3. MyCache myCache = new MyCache();
  4. //写入操做
  5. for (int i = 1; i <= 5; i++) {
  6. final String temp = i+" ";
  7. new Thread(()->{
  8. myCache.put(temp,temp);
  9. },String.valueOf(i)).start();
  10. }
  11. //读取操作
  12. for (int i = 1; i <= 5; i++) {
  13. final String temp = i+" ";
  14. new Thread(()->{
  15. myCache.get(temp);
  16. },String.valueOf(i)).start();
  17. }
  18. }
  19. }
  20. /*
  21. 自定义缓存 set get
  22. */
  23. class MyCache {
  24. private volatile Map<String,Object> map = new HashMap<>();
  25. ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
  26. //存,写
  27. public void put(String key,Object value){
  28. readWriteLock.writeLock().lock();
  29. try {
  30. System.out.println(Thread.currentThread().getName()+"写入"+key);
  31. map.put(key,value);
  32. System.out.println(Thread.currentThread().getName()+"写入成功"+key);
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. } finally {
  36. readWriteLock.writeLock().unlock();
  37. }
  38. }
  39. //取,读
  40. public void get(String key){
  41. readWriteLock.readLock().lock();
  42. try {
  43. System.out.println(Thread.currentThread().getName()+"读取"+key);
  44. Object o = map.get(key);
  45. System.out.println(Thread.currentThread().getName()+"读取成功"+o);
  46. } catch (Exception e) {
  47. e.printStackTrace();
  48. } finally {
  49. readWriteLock.readLock().unlock();
  50. }
  51. }
  52. }

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/956094
推荐阅读
相关标签
  

闽ICP备14008679号