线程执行时需要分配CPU资源,CPU按照时间片分给线程执行,在线程时间片用完的情况下,需要保存现场,将执行权转让给其他线程。当该线程重新有机会执行时,需要加载之前的现场信息,然后执行。
从保存现场 到下次加载执行, 就是一次上下文切换,英文叫: context switch
在linux中,可以通过vmstat来查看系统的context switch次数:
System
in: The number of interrupts per second, including the clock.
cs: The number of context switches per second.
我们看到此时OS的cs基本在1000以内。
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 404644 66656 619388 0 0 0 20 157 309 1 0 99 1 0 0 0 0 404644 66656 619396 0 0 0 0 192 529 2 2 97 0 0 0 0 0 404644 66656 619396 0 0 0 0 516 1573 8 5 88 0 0 0 0 0 404644 66656 619396 0 0 0 0 610 656 3 4 93 0 0 0 0 0 404644 66656 619396 0 0 0 0 480 575 2 2 96 0 0 0 0 0 404644 66656 619396 0 0 0 0 841 1238 3 4 93 0 0 0 0 0 404644 66656 619396 0 0 0 0 465 570 2 5 93 0 0
我们执行一个java程序,2个线程相互等待执行唤醒,继续观察context。
此时发现cs基本都在2W多.
另外,发现in也很多,in是中断次数,因为我们用了LockSupport.
r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 397152 66808 619640 0 0 0 0 20800 83443 15 32 53 0 0 1 0 0 397152 66808 619640 0 0 0 0 29901 62160 2 26 72 0 0 1 0 0 397152 66808 619640 0 0 0 0 24617 51618 2 21 77 0 0 1 0 0 397152 66816 619632 0 0 0 48 26312 54760 1 26 74 0 0 1 0 0 397152 66816 619640 0 0 0 0 27106 58009 1 22 77 0 0 1 0 0 397152 66816 619640 0 0 0 0 27557 57114 2 23 75 0 0 1 0 0 397152 66816 619640 0 0 0 0 23964 49911 1 20 78 0 0 1 0 0 397152 66816 619640 0 0 0 0 21619 45313 1 23 76 0 0 2 0 0 397028 66816 619640 0 0 0 0 23673 53251 4 20 75 0 0 1 0 0 397028 66824 619632 0 0 0 12 21042 52601 8 26 66 1 0 1 0 0 396508 66824 619640 0 0 0 0 29707 60314 3 22 75 0 0
同时我们看到,CPU的使用率上,20+% 都用于sys,说明context switch在浪费CPU