自旋锁
首先我们需要理解:阻塞还有唤起线程都需要操作系统切换CPU状态去完成,这种状态转换需要耗费处理器时间,如果同步代码块中的任务十分简单,可能切换状态的时间要大于我们处理同步资源的时间了。
在许多场景中,同步资源的锁定时间很短,为了这一小段时间去切换线程,线程挂起和恢复现场的花费会让系统得不偿失。如果物理机器有多个处理器,能够让两个或以上的线程同时并行执行,我们就可以让后面那个请求锁的线程不放弃CPU的执行时间,看看持有锁的线程是否很快就会释放锁。
而为了让线程等一下!我们就需要让线程自旋。如果在自旋完成后前面锁定同步资源的线程已经释放了锁,那么当前线程就可以不必阻塞而是直接获取同步资源,从而避免切换线程的开销。这就是自旋锁。
自旋锁本身存在缺点
他不能代替阻塞,自旋等待虽然避免了切换线程的开销,但他要占用处理器时间。如果锁占用同步资源的时间很短,那么自旋锁是很好的选择,但如果占用时间过长,那不可能让线程一直自旋等待,会浪费处理器资源。需要一个限制!如果自旋超过了限定次数(默认是10次,可以使用-XX:PreBlockSpin来更改)没有成功获得锁,就应当挂起线程。