Java多线程会频繁的创建和切换上下文,这样的操作会影响多线程的执行速度.
上下文切换
JAVA虚拟机的多线程是通过线程轮流切换并分配CPU时间片的方式实现的.
CPU通过给每个线程分配CPU时间片来让线程执行代码,时间片是CPU分配给线程执行的时间,CPU通过不停的切换线程,并给线程时间片让它执行指令,这个时间片非常非常的短,一般是几十毫秒,让我们感觉多个线程在同时执行.
CPU通过这种时间片分配的算法来循环执行任务,当前线程任务的时间片用完之后会切换到下一个线程任务.一个处理器(如果是多核处理器来说是一个内核)只会执行一条线程中的指令.因此,为了线程切换后能恢复到上次正确的执行位置,在切换前会保存上一个任务的状态(JVM中的程序计数器就是这种状态的体现).
线程从消耗完时间片保存当前执行的状态再到获取下一次时间片加载这个状态的过程,我们称之为上下文切换,这种切换会影响多线程的执行速度.
多线程控制不当,比如锁竞争激烈就会不停的导致上下文切换.
既然上线文切换是系统层级的,那么我们有办法去减少这种切换带来的消耗吗?答案是不能,如果使用JAVA多线程处理任务,这种开销我们无法避免.但我们有别的一些方法去减少上下文切换.
减少上下文切换
- CAS算法:JAVA的Atomic包使用CAS算法,无需加锁.可以阅读源码参考.
- 无锁并发编程:使用别的办法避免共享对象从而产生锁.比如ThreadLocal.
- 使用最少线程:避免创建不需要的线程,空闲的线程会进入等待状态.
- 协程:单线程中实现多任务的调度,在单线程里维持多个人物之间的切换.