美文网首页
java性能调优

java性能调优

作者: 茨木妖刀姬 | 来源:发表于2021-03-15 18:06 被阅读0次

    一. 锁优化

    针对于synchronized获取锁方式,jvm使用了锁升级的优化方式,就是先使用  **偏向锁**,优先同一线程然后再次获取锁,如果失败,就升级为  **CAS轻量级锁**,如果失败就会短暂**自旋**, 防止线程被系统挂起, 最后如果都失败就升级为 **重量级锁**.
    

    因此总结了以下几点经验:

    1.减少锁的时间
          不需要同步执行的代码,能不放在同步代码块里就不要放在同步代码块里,可以让锁尽快释放.
    
    2.减少锁的粒度
          共享资源数决定锁的数量,有一组资源定义一把锁,而不是多组资源公用一把锁,增加并行度,从而降低锁竞争,典型如分段锁..
    
    3.减少加锁的次数
          假如有一个循环,循环内的操作需要加锁,我们需要把锁放到循环外面,否则每次进出循环,都要加锁.
    
    4.使用读写锁
          业务细分,读操作加读锁,写操作加写锁,只能单线程写,参考计数器案例
          例如: 原来实现方式是采用  Reentrantlock + map实现,  可以改为ReentrantReadWriteLock + ConcurrentHashMap进行优化
          ps:  使用场景是 -->读多写少
    
    5.善用volatile
          volatile的控制比synchronized更强量化,在某些变量上不涉及多步打包操作,和原子性问题,可以加以运用..如ConcurrentHashMap的get操作,而不是加锁.
    

    二. 线程池参数优化

    1.corePoolSize
      核心线程数, 一旦有任务进来,在core范围内会立即创建线程进入工作,所以这个值应该参考业务并发量在绝大多数时间内的并发情况,同时分析任务的特性.
    
      高并发执行时间短的,要尽可能小的线程数,如配置cpu个数+1,减少线程上下文切换,因此他不怎么占时间,让少量线程快跑干活.
    
      并发不高,任务执行时间长的要分开看:  如果时间都花在了io上,那就调大CPU,如配置两倍的CPU个数+1,不能让CPU闲下来,线程多了并行处理更快.如果时间都花在了运算上,运算的任务还很重,本身就很占CPU,那尽量减少CPU,减少切换时间.参考第一条...
    
    2.workqueue
      任务队列,用于传输和保存等待执行任务的阻塞队列,这个需要根据你的业务可接受的等待时间.是一个需要权衡时间还是空间的地方,如果你的机器CPU资源紧张,jvm内存够大,同时任务又不是那么紧迫,减少coresize,加大这里,如果你的CPU不是问题,堆内存比较敏感比较害怕内存溢出,同时任务要求快点相应,那么减少这里..
    
    3.maximumPoolSize
      线程池最大数量,这个值和队列搭配使用,如果你采用了无界队列,这个参数失效,同时要注意,这个队列盛满,同时达到max的时候,再来任务可能会丢失,
    
    如果你的任务波动比较大,同时对任务波峰来的时候,实时性要求比较高,也就是来的时候很突然并且都是着急的,那么调小队列,加大这里, 如果你的任务不着急,可以慢慢做,那就扔队列吧.
    
      队列与max是一个权衡.  队列空间换时间,多花内存少占cpu,轻视任务紧迫度,. max舍得cpu线程开销.少占内存,给任务最快的响应.
    
    4.keepalivetime
      线程存活的时间,超出该时间后,线程会从max下降到core,很明显,这个决定了你养闲人所话的代价,如果你不缺cpu,同时任务来的时间没法琢磨,波峰波谷间隔比较短.经常性的来一波.  那么适当的延长销毁时间,避免频繁创建和销毁线程带来的开销.  如果你的任务波峰出现后,很长一段时间不在出现,间隔比较久,那么适当的调小该值,让闲着不干活的线程尽快销毁,不要占据资源.

    相关文章

      网友评论

          本文标题:java性能调优

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