在看多线程的时候,为了解决多线程下的对数据操作的原子性问题,往往采用synchronized同步锁,但是synchronized是通过加锁来实现的,对于未获得锁的线程,对数据进行读操作时,会被阻塞挂起,阻塞和唤醒是非常消耗资源的,那时候不明白线程阻塞挂起以及唤醒是如何消耗系统资源的,网上大多数是说线程的上下文切换和线程的调度消耗系统资源,还是讲的不够清楚,这几天一直在研究这个问题,今天写一下自己的理解。
java的线程是映射到操作系统的原生线程上的,如果要阻塞或者唤醒一个线程,则需要在用户态和内核态之间切换,这种切换会消耗大量的资源,因为,用户态和内核态都有自己的内存空间和专用的寄存器等,用户态切换到内核态时,需要传递许多参数和变量给内核,同时内核也需要保存好用户态在切换时的一些寄存器的值和变量,以便内核态调用结束切回到用户态能够继续工作。
如果线程状态频繁的切换,则会耗费很多cpu的处理时间;如果需要同步的代码块很简单,则获取锁挂起操作消耗的时间比用户代码执行的时间还要长,这种同步策略明显是失败的。