- 自旋锁释义:
请求锁的线程(假设为线程A)再未获得锁的时候,不进入阻塞状态,而是让它「再执行一会」即占用CPU一会,看看持有锁的线程是否很快释放锁资源。但是为了让这个线程A进入「等待」的状态,需要让它执行一个忙循环(自旋),这项技术称为自旋锁。
- 自旋锁的优劣势分析
- 线程A的状态切换是由系统进行的,而这个过程则会消耗系统资源的,如果请求锁的「忙循环」时在一个很小的时间片之内就得到锁,就能提升线程A的执行效率,至少节约了由系统进行的线程A由阻塞状态--->运行状态的时间。
- 反之如果线程A 在执行「忙循环」时迟迟得不到锁资源,那么就会造成这个「忙循环」占用大量的cpu资源。
- 自旋锁本身是有缺点的,它不能代替阻塞。自旋等待虽然避免了线程切换的开销,但它要占有处理器的时间,如果锁被占有的时间很短,自旋等待的效果就会非常好。反之,如果锁被占用的时间很长,那么自旋的线程只会白浪费处理器资源。所以,自旋等待的时间必须要有一定的限度,如果自旋超过了限定次数(默认是10次)没有成功获得锁,就应当挂起线程。
- 这两者的状态大致可以用下面这个流程图来说明
- 在JDK1.6之后引入了自适应自旋锁。自适应意味着自旋的时间(次数)不再固定,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。如果在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程正在运行中,那么虚拟机就会认为这次自旋也是很有可能再次成功,进而它将允许自旋等待持续相对更长的时间。如果对于某个锁,自旋很少成功获得过,那在以后尝试获取这个锁时,将可能省略掉自旋过程,直接阻塞线程,避免浪费处理器资源。