乐观锁、悲观锁、自旋锁、Synchronized 同步锁
乐观锁
乐观锁是一种乐观思想,即认为读多写少,遇到并发的可能性低,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采取在写时先读取当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新)
java中的乐观锁基本都是通过CAS操作实现的,CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。
悲观锁
悲观锁就是一种悲观思想,即认为写多读少,遇到并发的可能性高,每次去拿数据都会认为数据被别人修改了,所以每次都需要加锁,这样别人想读写这个数据就会block知道拿到锁,java中的悲观锁就是Synchronized。
自旋锁
自旋锁的原理非常简单,如果持有锁的线程能在很短的时间内释放资源,那么等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,他们只需要等一等(自旋)等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换消耗
线程自旋是需要消耗cpu的,说白了就是CPU在做无用功,如果一直获取不到锁,那线程
也不能一直占用cup 自旋做无用功,所以需要设定一个自旋等待的最大时间。
如果持有锁的线程执行的时间超过自旋等待的最大时间扔没有释放锁,就会导致其它争用锁
的线程在最大等待时间内还是获取不到锁,这时争用线程会停止自旋进入阻塞状态。
Synchronized 同步锁
Synchronized 他可以把任意一个非NULL的对象当做锁,它属于独占式的悲观锁,同时属于可重入锁
Synchronized 作用范围
作用方法时,锁住的是对象的实例(this)
作用于静态方法时,锁住的是Class实例
作用于对象时,锁住的是以该对象为锁的代码块