zoukankan      html  css  js  c++  java
  • 性能测试学习第十天-----性能案例分析之线程阻塞

    一、定义
      在多线程情况下,如果一个线程对拥有某个资源的锁,那么这个线程就可以运行资源相关的代码。而其他线程就只能等待其执行完毕后,才能继续争夺资源锁,从而运行相关代码。

    二、场景
      车票售卖系统,当前剩余车票1张,此时有A、B、C、D四个用户同时来购票,系统开启了四个线程来执行业务操作,其中:
        A线程刚执行了step1;
        CPU将执行权切换到B线程;
        B线程顺利的执行了step1和step2,此时剩余票数为0;
        CPU将执行权又切换到A线程,A线程继续执行step2,此时票数为-1,多卖出去一张票!出现异常业务数据。
      这种情况就是多线程模式下的数据安全问题。

    三、解决方案

      在多线程的情况下,如果存在修改共享数据的操作,就要对操作步骤进行加锁,拥有锁的线程才可以执行相关代码。没有锁的线程只能等待其释放锁后,才有资格继续执行代码。
        synchronized(this){
          step1:判断车票数量;
          step2:车票数量-1;}    
    四、场景复现:

      车票售卖系统,当前剩余车票1张,此时有A、B、C、D四个用户同时来购票,系统开启了四个线程来执行业务操作。

        A线程最先执行代码块,并进行加锁操作,执行了step1,此时A线程拥有锁;
        CPU将执行权切换到B线程,B线程准备执行代码块,发现代码块已经加锁,只能继续等待;
        CPU将执行权切换到C线程,发现代码块已经加锁,只能继续等待;
        CPU将执行权切换到D线程,发现代码块已经加锁,只能继续等待;
        CPU将执行权切换到A线程,自身拥有锁,继续执行step2,票数为0;
      后续其他线程再次执行到代码块的时候,因为票数已经为0了,所以就不再继续执行后续操作。这样就不会出现数据异常问题了。

    五、Log4j的线程阻塞问题

      Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以
    控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

    • Log4j的日志级别Level 描述:  

      ALL 各级包括自定义级别
      DEBUG 指定细粒度信息事件是最有用的应用程序调试
      ERROR 错误事件可能仍然允许应用程序继续运行
      FATAL 指定非常严重的错误事件,这可能导致应用程序中止
      INFO 指定能够突出在粗粒度级别的应用程序运行情况的信息的消息
      OFF 这是最高等级,为了关闭日志记录
      TRACE 指定细粒度比DEBUG更低的信息事件
      WARN 指定具有潜在危害的情况
      级别越低,日志越多,日志量:ALL > DEBUG > INFO > WARN > ERROR > FATAL

    六、线程阻塞问题排查流程

      /pinter/case/block:  TPS无明显变化,CPU压不上去,jvisualvm查看截图如下,存在大量红色监视状态的线程。

            

      1、做线程dump。 使用jstack 线程号 > t.log
      2、在dump文件或log 中搜索关键字"BLOCKED"、"TIME_WAITTING",查看每种状态的count数量
      3、按照上述关键字搜索,查看跟本系统有关的业务代码堆栈信息

    七、解决方案

      1、减少代码中没有必要的日志输出
      2、如果可以,修改WEB-INF/classes/log4j.popertites配置,提升日志级别,以减少日志;将下图中的INFO改成ERROR后,重启tomcat;

        日志第一行意思是:INFO级别日志打印到console控制台,滚动日志

                  

      3、如果可以,更换其他的日志组件,如Log4j2、Logback等

  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/qingyuu/p/11603662.html
Copyright © 2011-2022 走看看