美文网首页
程序员修炼之道33-打破时域耦合

程序员修炼之道33-打破时域耦合

作者: DZQANN | 来源:发表于2022-02-24 22:08 被阅读0次

这一章讲的是多线程。我们的开发中用到多线程的地方比较少,主要的原因都是没必要,使用多线程带来的风险远比提高的速度多。

这节介绍了如何分析使用多线程的场景。这个地方讲的内容我们肯定是用不到的,场景不一样,不过它讲的内容倒很值得我们学习。

先说一下场景的区别,我们的系统里用到多线程的场景是:同一个Task需要循环执行多次。书里介绍的场景是不同Task之间的并行执行。

单一Task使用并发的判断依据

对于我们的这种场景,需不需要使用我觉得可以有几个角度去看:

  1. 单个Task的执行速度

    这个我是放在第一位的,如果单个Task执行时间只有几十几百毫秒,串行循环执行几千几万次也是可以接受的。这个时候如果使用多线程,系统调度的花销会比较大。

    有一个例子,之前的一个报表,需要对几百组单子进行统计分析,一组单子的处理时间在几分种左右,这个情形就可以使用多线程了。我们就是使用了Java8的parallelStream,速度提升了不少

  2. 共享资源

    共享资源的竞争结果,基本也是将并发变成了串行。在设计多线程场景之前,要先想清楚线程之间的资源是不是完全独立的,如果出现了共享资源,就需要三思了

  3. 数据库锁

    这个和之前一点是一样的,共享资源可以说是内存中的共享资源,这里说的是站在持久层的角度看共享资源。之前发生过的例子,我们的Domain结构中,Tariff是从属于Contract的,Tariff的version改变也会使Contract的version改变。我们有两个节点可以处理Q中的消息,这个消息是用来更新Tariff的信息的,这就导致了很严重的并发问题,如果两个节点同时更新了同一个Contract下的Tariff,就会造成乐观锁,从结果来看60%多的消息因为乐观锁而失败。最后还是使用了别的方法去掉了并发。�

此外,并发带来的另外一个副作用是很难追查问题,之前在看代码的时候发现了很多并发问题的隐患,如果发生了产品Exception也很难追查当时的状态

public class Service {
  
  private static String a;
  
  public static processString(String b) {
    if (!b.equals(a)) {
      a = b;
    }
    ... others
  }
}

@Service
public class ServiceB {
  private String a;
  
  public void processString(String a) {
    this.a = a;
  }
}

这两个情况也都比较简单,写代码的人也不是故意的,有时候是一不小心引入的问题,但总是难免会犯错,真的防止这种事情可能需要加一些Check Style机制?

相关文章

网友评论

      本文标题:程序员修炼之道33-打破时域耦合

      本文链接:https://www.haomeiwen.com/subject/unyfrrtx.html