上下文切换
线程得以执行是依靠CPU给它分配了时间片。当前线程消耗完时间之后,将会阻塞(挂起,等待),换成另一个线程执行它的任务,但是线程切换前会保存上一个线程的状态,以便该线程再次获得时间片切换回该线程(通过程序计数器 (Program Register)实现)。这种从任务保存到再加载的过程被称为上下文切换。
注:有时候并发操作耗时比串行更多的原因是:上下文切换(也可笼统地称为线程调度)和线程创建的时间开销太高了。
锁的四种状态
在JDK 1.6后,JVM引入了四种锁状态:无锁状态,偏向锁,轻量级锁,重量级锁。通过CAS在对应对象的Mark Word中设置标记实现。
- 无锁状态:当线程间不发生对资源对争抢时,这个资源是无锁状态。
- 偏向锁:大多数情况,资源不仅不存在争抢,还总是被同一个线程获得,这时候为了消除获取释放锁时的CAS开销(当获取或释放锁时,都要通过CAS操作奖线程id记录到锁对象的Mark Word中),将资源里的锁标记设置为偏向锁的标记,看起来像是某个线程得到了偏护。当第二个线程也来争抢这个资源时,偏向锁升级为轻量级锁。
- 轻量级锁:当获得偏向锁的资源发生线程争抢时,偏向锁升级为轻量级锁。
- 重量级锁:当获得轻量级锁的资源发生线程争抢时,轻量级锁升级为重量级锁。