针对单一key加读写锁

打印 上一主题 下一主题

主题 826|帖子 826|积分 2493

一、什么是读写锁
读写锁是JDK1.5提供的一个工具锁,适用于读多写少的场景,将读写分离,从而提高并发性。
二、读写锁的特点
读锁是共享锁,写锁是排他锁,读锁和写锁不能同时存在;
读锁不能升级为写锁;
写锁可以降级为读锁;
三、锁的本质
锁的本质就是锁住一块资源而不是一块代码. 在常见的一些代码实现都是加一把大锁,将这一块代码资源统一加锁,无法针对资源进行精确进行锁控制.
四、代码实现
`
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Slf4j
public class UserDefinedLock {
  1. final ConcurrentHashMap<String, ReadWriteLock> map = new ConcurrentHashMap<>();
  2. public UserDefinedLock() {
  3. }
  4. /**
  5. * 从map里获取锁 如果存在则返回 不存在则创建
  6. *
  7. * @param key key
  8. * @return lock
  9. */
  10. public void createOrGetLock(String key) {
  11.     synchronized (key.intern()) {
  12.         map.compute(key, (k, lock) -> {
  13.             if (lock == null) {
  14.                 lock = new ReentrantReadWriteLock();
  15.             }
  16.             return lock;
  17.         });
  18.     }
  19. }
  20. /**
  21. * 获取锁 会阻塞
  22. *
  23. * @param key key
  24. */
  25. public void writeLock(String key) {
  26.     map.get(key).writeLock().lock();
  27. }
  28. public void readLock(String key) {
  29.     map.get(key).readLock().lock();
  30. }
  31. /**
  32. * 释放锁 必须由申请锁的线程进行调用
  33. *
  34. * @param key key
  35. */
  36. public void unWriteLock(String key) {
  37.     ReadWriteLock lock = map.get(key);
  38.     if (null != lock) {
  39.         try {
  40.             lock.writeLock().unlock();
  41.         } catch (Exception e) {
  42.             log.error("释放写锁失败,key:{}, msg:{}", key, e.getMessage());
  43.         }
  44.     }
  45. }
  46. public void unReadLock(String key) {
  47.     ReadWriteLock lock = map.get(key);
  48.     if (null != lock) {
  49.         try {
  50.             lock.readLock().unlock();
  51.         } catch (Exception e) {
  52.             log.error("释放读锁失败,key:{}, msg:{}", key, e.getMessage());
  53.         }
  54.     }
  55. }
  56.   public static void main(String[] args) {
  57.         UserDefinedLock userDefinedLock = new UserDefinedLock();
  58.         ArrayList list = new ArrayList<String>();
  59.     for (int i = 0; i < 5; i++) {
  60.         String key = String.valueOf("测试" + i);
  61.         new Thread(() -> {
  62.             try {
  63.                 userDefinedLock.createOrGetLock(key);
  64.                 userDefinedLock.readLock(key);
  65.                 System.out.println("-----" + key + "----");
  66.                 list.add(key);
  67.             } catch (Exception e) {
  68.                 e.printStackTrace();
  69.             } finally {
  70.                 try {
  71.                     Thread.sleep(1000);
  72.                 } catch (InterruptedException e) {
  73.                     e.printStackTrace();
  74.                 }
  75.                 userDefinedLock.unReadLock(key);
  76.             }
  77.         }, "read-" + key).start();
  78.     }
  79. }
复制代码
}
`

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连全瓷种植牙齿制作中心

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表