zoukankan      html  css  js  c++  java
  • 第一部分:并发理论基础04->互斥锁(下),如何用一把锁保护多个资源

    1.一把锁保护多个资源

    受保护资源和锁的关系是N:1

    2.保护没有关联关系的多个资源

    银行业务中针对账户余额的取款操作
    银行业务中针对账户密码的更改操作
    为账户余额和密码修改分配不同的锁来解决并发问题

    代码,两把锁ballLock,pwLock分别保护不同的资源

    
    class Account {
      // 锁:保护账户余额
      private final Object balLock
        = new Object();
      // 账户余额  
      private Integer balance;
      // 锁:保护账户密码
      private final Object pwLock
        = new Object();
      // 账户密码
      private String password;
    
      // 取款
      void withdraw(Integer amt) {
        synchronized(balLock) {
          if (this.balance > amt){
            this.balance -= amt;
          }
        }
      } 
      // 查看余额
      Integer getBalance() {
        synchronized(balLock) {
          return balance;
        }
      }
    
      // 更改密码
      void updatePassword(String pw){
        synchronized(pwLock) {
          this.password = pw;
        }
      } 
      // 查看密码
      String getPassword() {
        synchronized(pwLock) {
          return password;
        }
      }
    }
    

    用不同的锁保护资源进行精细化管理,能够提升性能,这叫做细粒度锁

    3.保护有关联关系的多个资源

    例如转账操作,账户A减少100,账户B增加100
    image

    不能用自己家的锁,保护别人家的大门一样

    4.使用锁的正确姿势

    一把锁保护多个资源
    很简单,A,B两个账户用的是一把锁就好了

    如何一把锁,什么套路?
    (1)2个Account对象都持有一个唯一的对象,这个对象再Account生成时传入

    
    class Account {
      private Object lock;
      private int balance;
      private Account();
      // 创建Account时传入同一个lock对象
      public Account(Object lock) {
        this.lock = lock;
      } 
      // 转账
      void transfer(Account target, int amt){
        // 此处检查所有对象共享的锁
        synchronized(lock) {
          if (this.balance > amt) {
            this.balance -= amt;
            target.balance += amt;
          }
        }
      }
    }
    

    (2)对Account.class类文件加锁

    
    class Account {
      private int balance;
      // 转账
      void transfer(Account target, int amt){
        synchronized(Account.class) {
          if (this.balance > amt) {
            this.balance -= amt;
            target.balance += amt;
          }
        }
      } 
    }
    

    image

    5.总结

    理清多个资源的关系
    资源之间没关系,很好处理。每个资源一把锁
    资源之间有关系,选择粒度更大的锁,锁要覆盖所有相关的资源

    原子性
    本质其实是不可分割,多个资源一致性要求。中间状态对外不可见
    不能用可变对象做锁

    原创:做时间的朋友
  • 相关阅读:
    PHP实反向代理-收藏
    微信小程序实例-获取当前的地理位置、速度
    Entity Framework Core 实现读写分离
    将ASP.NET Core应用程序部署至生产环境中(CentOS7)(转)
    Centos 7防火墙firewalld开放80端口
    Asp.net Core 使用Redis存储Session
    .net core 使用Autofac依赖注入
    .net core 1.0 实现负载多服务器单点登录
    用ASP.NET Core 1.0中实现邮件发送功能-阿里云邮件推送篇
    阿里大鱼.net core 发送短信
  • 原文地址:https://www.cnblogs.com/PythonOrg/p/14931448.html
Copyright © 2011-2022 走看看