zoukankan      html  css  js  c++  java
  • Java并发编程艺术系列-一、并发编程问题与解决

    一、并发编程问题与解决

    • 上下文切换
    • 死锁
    • 资源限制

    1.1 上下文切换

    1.1.1 问题

    • CPU通过时间片分配算法来循环执行任务,当前任务一个时间片执行完后会切换到下一个 任务,要保存上一个任务的状态,有一定的开销
    • 多线程不一定快 - 因为上下文切换的开销

    1.1.2 解决

    • 无锁并发编程:根据id将数据hash分配到不同线程来避免使用锁
    • CAS算法:自旋锁(注意:自旋CPU消耗大)
    • 最少线程:避免创建不需要的线程,线程越多,上下文就多,等待线程也多,切换也频繁
    • 协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

    1.1.3 解决实战

    • 工具

      • 使用Lmbench3[1]可以测量上下文切换的时长。

      • 使用vmstat可以测量上下文切换的次数。

      • 下面是利用vmstat测量上下文切换次数的示例。

        $ vmstat 1 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- 
        r b swpd free buff cache si so bi bo in cs us sy id wa st 
        0 0 0 127876 398928 2297092 0 0 0 4 2 2 0 0 99 0 0 
        0 0 0 127868 398928 2297092 0 0 0 0 595 1171 0 1 99 0 0 
        0 0 0 127868 398928 2297092 0 0 0 0 590 1180 1 0 100 0 0 
        0 0 0 127868 398928 2297092 0 0 0 0 567 1135 0 1 99 0 0
        

        CS(Content Switch)表示上下文切换的次数,从上面的测试结果中我们可以看到,上下文每1秒切换1000多次。

    • 1.jstack命令dump线程信息

      jstack 35031 > dump31
      
    • 2.统计线程状态

      grep java.lang.Thread.State dump31 | awk '{print $2$3$4$5}' | sort | uniq -c
      39 RUNNABLE 
      21 TIMED_WAITING(onobjectmonitor) 
      6 TIMED_WAITING(parking) 
      51 TIMED_WAITING(sleeping) 
      305 WAITING(onobjectmonitor) 
      3 WAITING(parking)
      
    • 3.打开dump文件查看WAITING(onobjectmonitor)发现是jboss线程,接收任务太少,大量线程闲着waitting

    • 4.配置jboss使用较少线程

    • 5.重新统计发现waitting少了,waitting线程少了,上下文切换就少,因为每一次从 WAITTING到RUNNABLE都会进行一次上下文的切换。可以使用vmstat命令验证一下

    1.2 死锁

    1.2.1 问题

    • 线程t1和线程t2互相等待对方释放锁。

    1.2.2 解决

    • dump线程查看出现问题的线程 java.lang.Thread.State: BLOCKED

    • 避免一个线程同时获取多个锁。

    • 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。

    • 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。

    • 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。

    1.3 资源限制

    1.3.1 问题

    • 硬件资源限制:网络带宽、硬盘读写、CPU处理速度
    • 软件资源限制:连接数(数据库,socket)
    • 受限于资源,多线程程序依然在串行执行,因为增加了切换上下文和资源调度的开销,反而效率更低

    1.3.1 解决

    • 硬件资源:多机部署解决
    • 软件资源:连接池、io多路复用
    • 根据资源限制调整并发配置。
  • 相关阅读:
    百度贴吧的数据抓取和分析(二):基础数据分析
    百度贴吧的数据抓取和分析(一):指定条目帖子信息抓取
    二十三种设计模式及其python实现
    经典排序算法及python实现
    从开发到部署,使用django创建一个简单可用的个人博客
    使用uWSGI+nginx部署Django项目
    ubuntu中彻底删除nginx
    阿里的秒杀系统是怎么设计的?
    多图详解!10大高性能开发核心技术
    关于Redis的几件小事 | 高并发和高可用
  • 原文地址:https://www.cnblogs.com/wod-Y/p/14815385.html
Copyright © 2011-2022 走看看