锁类型
- 乐观锁&悲观锁
- 自旋锁&非自旋锁
- 可重入锁&不可重入锁
- 无锁&轻量级锁&偏向锁&重量级锁
- 互斥锁&共享锁
- 公平锁&非公平锁
1.乐观锁&悲观锁
乐观锁:乐观锁乐观的认为,多线程同步数据时,其他线程不会对数据有任何操作。只有当做更新操作的时候才会检查数据是否被修改。如果没有被修改,就进行更新操作,如果被修改了,就报错,或者进行重写写入
悲观锁:悲观锁悲观的认为,在进行多线程数据同步时,其他线程一定会进行数据的修改,因此在进行操作时一定要进行synchronized和lock上锁
2.自旋锁&非自旋锁
自旋锁:当一个数据被上锁后,其他的线程就在就绪车间一直挤着。当锁被释放后在去争抢锁。
坏处:如果对数据的操作时间较长,锁迟迟没有释放。外面的线程会很消耗cpu资源。因此给自旋锁设置了限定词次数,到达一定次数后就会进入等待车间。JDK6中加入了自适应自旋锁对限定次数进行了优化,限定次数不再是固定不变了,会更具上一次的锁释放情况动态的调整自旋次数
非自旋锁:当一个数据被上锁后,其他的线程会被放入等待车间,当锁被释放的时候才会唤醒notify他们。每次阻塞锁和唤醒锁的操作都是极其耗费内存的,这样的设计特别不好
3.可重入锁&不可重入锁
可重入锁:递归中用的较多,当一个线程获取锁后可以在其内部继续获取锁,并用一个变量记录锁的数量
不可重入锁:一个线程获取锁后在其内部无法在获取锁,进入死锁状态
4.无锁,偏向锁,轻量级锁,重量级锁
无锁:多线程对数据进行操作的时候不上锁,但是只有一个线程能成功进行访问和修改
偏向锁:偏向锁记录了一个经常对数据进行操作的线程,这个线程可以自动获取锁,降低了获取锁的资源消耗。并且在并发编程中一般都是一个线程多次获取同一个锁
轻量级锁:偏向锁获取锁后,另外一个线程要获取锁,就会升级为轻量级锁
重量级锁:当有轻量级锁后,还有线程要获取锁时,就自动升级为重量级锁
5.互斥锁(排他锁)&共享锁
互斥锁:当数据被一个线程获取互斥锁后,那么这个数据就不能在获取其他的锁。互斥锁可以进行读写操作
共享锁:当数据被一个线程获取共享锁后,这个数据仍然能获取锁,只不过只能获取共享锁(递归的可重入锁应该属于共享锁)共享锁只能进行读的操作,适合大量数据的读操作
6.公平锁&非公平锁
公平锁:当一个线程获取锁后,其他线程依次进行排队,线程们按照顺序获取锁。
非公平锁:当一个线程获取锁后,其他线程进行争抢,运气好就能获得锁,不必按顺序排序获取锁。有时线程不必进行阻塞状态就可以直接获取锁。
参考文章:https://tech.meituan.com/2018/11/15/java-lock.html