乐观锁:它这个锁和名字一样都是比较乐观的,一直假设没有冲突,有冲突也就简单处理一下冲突,在修改的时候会检查一下有没有人进行修改过,这一般都是用版本号机制和CAS算法进行实现的。这和单纯的互斥锁来说,这个锁更加轻量一点。
悲观锁:这个锁和乐观锁恰恰相反,它对人生比较悲观,认为别人会修改自己的东西,所以,在每次修改东西的时候都会上锁,防止有人修改它的东西,这个锁的效率比较低。
应用场景:乐观锁一般应用在线程的冲突比较少,也就是说读操作比较多,写操作比较小。悲观锁则和它是相反的,一般应用在线程冲突比较多,写操作比较多的情况下。
2.重量级锁轻量级锁重量级锁:它的开销比较的大,需要在内核态中进行完成。悲观锁是一个重量级锁。
轻量级锁:它的开销比较小,在用户态中完成就行。乐观锁就是一个轻量级锁。
这种锁只看它的开销大不大,而不看它的适用场景。
轻量级锁一般都是通过版本号机制或CAS算法进行实现的。但对用重量级锁来说不是,这与操作系统的内核有关。cpu一般会提供一些特殊指令,操作系统会对这些指令进行封装一层,提供一个mutex(互斥量),在Linux种就会提供一个这样的接口供用户进行加锁解锁。一般来说,如果锁是通过调用mutex来进行实现的,那么这个锁就是一个重量级锁。
3.自旋锁和挂起等待锁挂起等待锁:如果线程获取不到锁就会堵塞等待,啥时候结束等待就要看cpu的调度策略,在挂起的时候是不吃cpu的资源的。
自旋锁:在获取不到线程的时候,锁就会一直进行获取,直到获取到锁。这种策略的优势在于节省线程调度的开销并且更能及时的获取到锁。缺点就是更加浪费cpu资源。
使用场景:1.如果使用的冲突概率比较低,那么使用自旋锁比挂起等待锁更合适。
2.如果线程持有锁的时间较,使用自旋锁比挂起锁更加合适。
3.如果不希望吃太多cpu资源,就使用挂起等待锁。
4.公平锁和非公平锁这两个锁比较好理解,线程如果满足先来后到的原则那么就是公平锁。如果不满足,是一起竞争的,那么就是非公平锁。
5.可重入锁和不可重入锁对一把锁连着加锁两次,如果是不可重入锁,就会发生死锁。但如果是可重入锁,那么它的里面会有一个计数器,来记录里面锁的个数,多加一把计数器就会加一,如果想解锁,需要等计数器变为0。
6.synchronized根据上面的策略就可以对synchronized先做出一个直观的认识 :
1 开始的时候是乐观锁如果发现线程冲突概率比较高,就会自动转为悲观锁。
2.synchronized不是读写锁。
3 synchromzed开始的时候是一个轻量级锁,如果锁被持有的时间较长/锁的冲突较高就会成为一个重量级锁。
4.synchromzed 是 一 个非公平锁 .
5 synchromzed 是 一 个可重入锁。
6.synchromzed为轻量级锁的时候,大概率是一个自旋锁,为重量级锁的时候大概率是一个自我等待锁。



