并发编程实战-读写锁ReentrantReadWriteLock使用

港控/mmm° 2022-12-08 05:38 306阅读 0赞

模拟一个简单的缓存管理

  1. public static void main(String[] args) {
  2. ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  3. Map<String, Object> map = new HashMap<>();
  4. // 读锁,共享锁
  5. ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
  6. // 写锁,独占锁
  7. ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
  8. /**
  9. * 读锁是共享锁,不会独占
  10. * 写锁是独占锁,独占CPU
  11. * 下面实现简单缓存功能,缓存存在,就直接读取,不存在,就写入缓存
  12. */
  13. Thread[] threads = new Thread[20];
  14. for (int i = 0; i < threads.length; i++) {
  15. // 缓存的key
  16. String key = String.valueOf(i % 5);
  17. threads[i] = new Thread(() -> {
  18. try {
  19. // 读锁
  20. readLock.lock();
  21. // 缓存已存在,直接从缓存中读取
  22. if (map.containsKey(key)) {
  23. System.out.println("[读锁]缓存中存在key=" + key + "," + Thread.currentThread().getName() +
  24. "拿到缓存中的值:" + map.get(key));
  25. } else {
  26. // 缓存不存在,先读锁解锁,然后加入写锁,
  27. // 判断缓存是否存在,存在,直接读取,不存在,写入缓存
  28. readLock.unlock();
  29. // 写入缓存,先加写锁
  30. try {
  31. writeLock.lock();
  32. if (!map.containsKey(key)) {
  33. Thread.sleep(1000);
  34. map.put(key, key);
  35. System.out.println("[写锁]缓存中不存在key=" + key + "," + Thread.currentThread().getName() + "写入缓存中的值:" + key);
  36. }
  37. // 这里要注意:这里抢占读锁,是为了避免在上面的写锁释放以后被其他写锁独占,从而覆盖了值。
  38. readLock.lock();
  39. System.out.println("[写锁]缓存中存在key=" + key + "," + Thread.currentThread().getName() +
  40. "拿到缓存中的值:" + map.get(key));
  41. } catch (InterruptedException e) {
  42. e.printStackTrace();
  43. } finally {
  44. writeLock.unlock();
  45. }
  46. }
  47. } finally {
  48. readLock.unlock();
  49. }
  50. });
  51. threads[i].start();
  52. }
  53. }
  54. 效果:
  55. [写锁]缓存中不存在key=0,Thread-0写入缓存中的值:0,时间:2020-09-18 17:16:39
  56. [写锁]缓存中存在key=0,Thread-0拿到缓存中的值:0,时间:2020-09-18 17:16:39
  57. [写锁]缓存中不存在key=1,Thread-1写入缓存中的值:1,时间:2020-09-18 17:16:40
  58. [写锁]缓存中存在key=1,Thread-1拿到缓存中的值:1,时间:2020-09-18 17:16:40
  59. [写锁]缓存中不存在key=2,Thread-2写入缓存中的值:2,时间:2020-09-18 17:16:41
  60. [写锁]缓存中存在key=2,Thread-2拿到缓存中的值:2,时间:2020-09-18 17:16:41
  61. [写锁]缓存中不存在key=4,Thread-4写入缓存中的值:4,时间:2020-09-18 17:16:42
  62. [写锁]缓存中存在key=4,Thread-4拿到缓存中的值:4,时间:2020-09-18 17:16:42
  63. [读锁]缓存中存在key=0,Thread-5拿到缓存中的值:0,时间:2020-09-18 17:16:42
  64. [读锁]缓存中存在key=4,Thread-9拿到缓存中的值:4,时间:2020-09-18 17:16:42
  65. [读锁]缓存中存在key=1,Thread-6拿到缓存中的值:1,时间:2020-09-18 17:16:42
  66. [读锁]缓存中存在key=4,Thread-14拿到缓存中的值:4,时间:2020-09-18 17:16:42
  67. [读锁]缓存中存在key=1,Thread-11拿到缓存中的值:1,时间:2020-09-18 17:16:42
  68. [读锁]缓存中存在key=0,Thread-10拿到缓存中的值:0,时间:2020-09-18 17:16:42
  69. [读锁]缓存中存在key=0,Thread-15拿到缓存中的值:0,时间:2020-09-18 17:16:42
  70. [读锁]缓存中存在key=2,Thread-12拿到缓存中的值:2,时间:2020-09-18 17:16:42
  71. [读锁]缓存中存在key=2,Thread-17拿到缓存中的值:2,时间:2020-09-18 17:16:42
  72. [读锁]缓存中存在key=4,Thread-19拿到缓存中的值:4,时间:2020-09-18 17:16:42
  73. [读锁]缓存中存在key=1,Thread-16拿到缓存中的值:1,时间:2020-09-18 17:16:42
  74. [读锁]缓存中存在key=2,Thread-7拿到缓存中的值:2,时间:2020-09-18 17:16:42
  75. [写锁]缓存中不存在key=3,Thread-8写入缓存中的值:3,时间:2020-09-18 17:16:43
  76. [写锁]缓存中存在key=3,Thread-8拿到缓存中的值:3,时间:2020-09-18 17:16:43
  77. [写锁]缓存中存在key=3,Thread-3拿到缓存中的值:3,时间:2020-09-18 17:16:43
  78. [写锁]缓存中存在key=3,Thread-13拿到缓存中的值:3,时间:2020-09-18 17:16:43
  79. [写锁]缓存中存在key=3,Thread-18拿到缓存中的值:3,时间:2020-09-18 17:16:43

发表评论

表情:
评论列表 (有 0 条评论,306人围观)

还没有评论,来说两句吧...

相关阅读