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

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

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

    原创:做时间的朋友
  • 相关阅读:
    trackr: An AngularJS app with a Java 8 backend – Part III
    trackr: An AngularJS app with a Java 8 backend – Part II
    21. Wireless tools (无线工具 5个)
    20. Web proxies (网页代理 4个)
    19. Rootkit detectors (隐形工具包检测器 5个)
    18. Fuzzers (模糊测试器 4个)
    16. Antimalware (反病毒 3个)
    17. Debuggers (调试器 5个)
    15. Password auditing (密码审核 12个)
    14. Encryption tools (加密工具 8个)
  • 原文地址:https://www.cnblogs.com/PythonOrg/p/14931448.html
Copyright © 2011-2022 走看看