Java中的锁机制
1.在Java中锁的分类
其实就是按照锁的特性分类的
- 公平锁,非公平锁
- 可重入锁
- 独享锁,共享锁
- 互斥锁,读写锁
- 乐观锁,悲观锁
- 分段锁
- 偏向锁,轻量级锁,重量级锁
- 自旋锁
公平锁,非公平锁
- 公平锁:是指多个线程按照申请顺序获取锁
- 非公平锁:是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的先获取,会造成优先级反转或者饥饿现象。
非公平锁的优点是单位时间内吞吐量高,ReentrantLock默认使用非公平锁是基于性能考虑,公平锁为了保证线程规规矩矩地排队,需要增加阻塞和唤醒的时间开销。如果直接插队获取非公平锁,跳过了对队列的处理,速度会更快。
当一个线程请求锁时,会先判断队列中有没有其他线程在等待,然后再判断线程有没有被其他线程占用,如果都没有的话才会获取这个锁,非公平锁则会直接判断这个锁哟没有被占用,没有的话就会直接占用,谓之插队。只有当有线程占用的时候才会排队。
可重入锁
可重入锁表示当前线程获取锁之后,这个线程的其他需要找个锁的操作也能正常执行,
不可重入锁表示当前线程获取这个锁之后,这个线程的其他后续操作不能通过这个锁操作对象。
独享锁,共享锁
- 独享锁:是指当前锁被该线程获取之后,到锁被释放之前,其他线程都不能获取该锁。
- 共享锁:是指当前锁可以被多个线程所共有,进行读取。
互斥锁,读写锁
- 互斥锁:当前线程在获取到这个锁之后,就不能再获得其他的锁,这个所也不能再被其他线程获取,相当于一对一关系,这个线程可以对锁进行读写操作
- 读写锁:多个读者可以同时进行读,只能有一个写者进行写操作,写者的优先级高于读者,当有写者需要获取锁时,所有读者必须阻塞等待,线程唤醒时优先考虑写者。
乐观锁,悲观锁
- 乐观锁:默认写操作很少,不会出现同时写的现象,所以写的时候并不会获取锁,只会在提交的时候获取锁,当两个线程同时提交的时候,其中一个线程提交成功,另一个提交失败,异常会返回给上层代码,让他们去处理。
- 悲观锁:比较悲观的一种态度,认为在对数据操作的时候一定会被修改,所以在整个数据处理规程中,将数据处于锁定状态。悲观锁往往依靠数据库提供的锁机制。
分段锁
- 分段锁的实现使用的是ConcurrentHashMap,把数据表看做一个大房子,ConcurrentHashMap相当于一个一个房子里有好多小房间,只要有人进了房间就把对应的房间锁起来,其他的还是可以被其他人访问的,HashTable相当于大仓库,只要需要访问其中的数据就要把整个仓库锁起来。
偏向锁,轻量级锁,重量级锁
本文来自博客园,作者:两小无猜,转载请注明原文链接:https://www.cnblogs.com/charlottepl/p/13373065.html