java并发线程优化之线程引入的开销

如何让多线程优于单线程程序,很简单的一个原则:多线程并行带来的优势要优于引入多线程带来的开销。


下面来讨论多线程在哪些方面会带来开销:


1,切换上下文

      产生原因举例:多线程竞争锁时被阻塞,该线程就会阻塞,会被jvm挂起,造成上下文切换,目的是为了新线程分配新的资源。

                                   如果线程数多于cpu内核数多会引起上下文的切换。

      如何分析上下文切换开销太大:unix系列的vmstat及windows系统的perfmon都能报告上下文切换占用时间,如果超过内核的10%时间,那就很有可能是线程阻塞

      或者竞争锁引起。

      vmstat命令各个列的含义如下表:

    

列名 含义
r 运行队列的长度,即等待执行的线程数目
b 处于阻塞状态或者等待IO完成状态的线程数目
in 系统中断的数目
cs 上下文切换的数目
us CPU执行用户态线程的时间占比
sys CPU执行系统态线程占用的时间占比,包含内核和中断两部分
wa CPU处于等待状态的时间占比(CPU等待状态即所有线程都处于被阻塞或者等待IO完成状态)
id CPU处于完全空闲状态的时间占比


2,内存同步

synchronized,volatile会设置memory barrier(内存关卡),要求必需使用内存关卡来进行缓存刷新,缓存无效,形成性能瓶颈,影响重排序

     如何进行优化:逃逸分析方法,简单的理解就是看该本地对象是否未被堆中对象引用,如果没有就可进行锁消除等操作,很多工作实际在jvm中的jit进行优化编译时

                                 就会做掉,比如常用的锁优化机制:自旋锁、锁消除、锁粗化、偏向锁等。


3,阻塞

   非竞争的同步由jvm完全掌控,而竞争的同步可能会需要os的活动,从而引起较大的开销,既然有竞争,竞争失败的线程肯定会引起阻塞。

    如果处理阻塞;两种方式:自旋、挂起

                               自旋应用场景:等待时间短

                               挂起:适合等待时间长



你可能感兴趣的:(java,多线程,优化,线程,并发)