写点什么

Java 开发三年月薪才 12K,你知道如何用面向对象思想写好并发编程吗?

发布于: 1 小时前
  return value;}synchronized long addOne(){  return ++value;}
复制代码


}


当然,实际工作中,很多的场景都不会像计数器这么简单,经常要面临的情况往往是有很多的共享变量,例如,信用卡账户有卡号、姓名、身份证、信用额度、已出账单、未出账单等很多共享变量。这么多的共享变量,如果每一个都考虑它的并发安全问题,那我们就累死了。但其实仔细观察,你会发现,很多共享变量的值是不会变的,例如信用卡账户的卡号、姓名、身份证。**对于这些不会发生变化的共享变量,建议你用 final 关键字来修饰。** 这样既能避免并发问题,也能很明了地表明你的设计意图,让后面接手你程序的兄弟知道,你已经考虑过这些共享变量的并发安全问题了。
# 二、识别共享变量间的约束条件识别共享变量间的约束条件非常重要。因为**这些约束条件,决定了并发访问策略。** 例如,库存管理里面有个合理库存的概念,库存量不能太高,也不能太低,它有一个上限和一个下限。关于这些约束条件,我们可以用下面的程序来模拟一下。在类 `SafeWM` 中,声明了两个成员变量 `upper` 和 `lower`,分别代表库存上限和库存下限,这两个变量用了 `AtomicLong` 这个原子类,原子类是线程安全的,所以这两个成员变量的 `set` 方法就不需要同步了。```javapublic class SafeWM { // 库存上限 private final AtomicLong upper = new AtomicLong(0); // 库存下限 private final AtomicLong lower = new AtomicLong(0); // 设置库存上限 void setUpper(long v){ upper.set(v); } // 设置库存下限 void setLower(long v){ lower.set(v); } // 省略其他业务代码}
复制代码


虽说上面的代码是没有问题的,但是忽视了一个约束条件,就是库存下限要小于库存上限,这个约束条件能够直接加到上面的 set 方法上吗?我们先直接加一下看看效果(如下面代码所示)。我们在 setUpper()setLower() 中增加了参数校验,这乍看上去好像是对的,但其实存在并发问题,问题在于存在竞态条件。这里我顺便插一句,其实当你看到代码里出现 if 语句的时候,就应该立刻意识到可能存在竞态条件。


我们假设库存的下限和上限分别是 (2,10),线程 A 调用 setUpper(5) 将上限设置为 5,线程 B 调用 setLower(7) 将下限设置为 7,如果线程 A 和线程 B 完全同时执行,你会发现线程 A 能够通过参数校验,因为这个时候,下限还没有被线程 B 设置,还是 2,而 5>2;线程 B 也能够通过参数校验,因为这个时候,上限还没有被线程 A 设置,还是 10,而 7<10。当线程 A 和线程 B 都通过参数校验后,就把库存的下限和上限设置成 (7, 5) 了,显然此时的结果是不符合库存下限要小于库存上限这个约束条件的。


public class SafeWM {   // 库存上限   private final AtomicLong upper = new AtomicLong(0);   // 库存下限   private final AtomicLong lower = new AtomicLong(0);   // 设置库存上限   void setUpper(long v){     // 检查参数合法性     if (v < lower.get()) {       throw new IllegalArgumentException();     }     upper.set(v);   }   // 设置库存下限   void setLower(long v){     // 检查参数合法性     if (v > upper.get()) {       throw new IllegalArgumentException();     }     lower.set(v);   }   // 省略其他业务代码}
复制代码


在没有识别出库存下限要小于库存上限这个约束条件之前,我们制定的并发访问策略是利用原子类,但是这个策略,完全不能保证库存下限要小于库存上限这个约束条件。所以说,在设计阶段,我们一定要识别出所有共享变量之间的约束条件,如果约束条件识别不足,很可能导致制定的并发访问策略南辕北辙。

如何获取免费架构学习资料?






由于篇幅限制小编,pdf 文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!有需要的程序猿(媛)可以戳这里即可免费获取哦

用户头像

还未添加个人签名 2021.07.29 加入

还未添加个人简介

评论

发布
暂无评论
Java开发三年月薪才12K,你知道如何用面向对象思想写好并发编程吗?