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.总结

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

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

    原创:做时间的朋友
  • 相关阅读:
    Linux测试端口是否连通的方法 -bash: telnet: 未找到命令
    Numpy全面学习资料
    python中调用java代码
    JDK的安装及环境变量配置
    python中logging模块的一些简单用法
    python得到代码所在文件的绝对路径
    Linux重定向(输入输出重定向)详解
    linux中grep命令的用法
    pyquery CSS选择器兄弟元素
    pyquery CSS选择器父级元素
  • 原文地址:https://www.cnblogs.com/PythonOrg/p/14931448.html
Copyright © 2011-2022 走看看