1.乐观锁
乐观锁是一种概念,它认为程序读多写少。
那么在获取数据的时候不加锁,而在更新的时候判断此期间这个值有没有改变(读版本号),如果没变就加锁更新,变化了就重新读取。(CAS)
2.悲观锁
悲观锁也是一种概念,它认为程序写多读少。
那么不管在获取数据的时候还是更新数据的时候都对操作进行加锁。
java中的悲观锁常见的就是关键词Synchronized。
AQS框架下的锁则是先尝试cas乐观锁去获取锁,获取不到,才会转换为悲观锁,如 RetreenLock
3.自旋锁
是一种非阻塞锁,也就是说,如果某线程需要获取锁,但该锁已经被其他线程占用时,
该线程不会被挂起,而是在不断的消耗CPU的时间,不停的试图获取锁,一旦锁被释放能立即获得锁(减少线程上下文切换,从用户态到内核态)
适用于对锁竞争不激烈,且同步代码执行时间快的程序。
4.同步锁
synchronized 它可以把任意一个非 null 的对象当作锁。
他属于独占式的悲观锁,同时属于可重入锁。
Synchronized 核心 组件
1) Wait Set:哪些调用 wait 方法被阻塞的线程被放置在这里;
2) Contention List:竞争队列,所有请求锁的线程首先被放在这个竞争队列中;
3) Entry List:Contention List 中那些有资格成为候选资源的线程被移动到 Entry List 中;
4) OnDeck:任意时刻,最多只有一个线程正在竞争锁资源,该线程被成为 OnDeck;
5) Owner:当前已经获取到所资源的线程被称为 Owner;
6) !Owner:当前释放锁的线程。
5.ReentrantLock
ReentantLock 继承接口 Lock 并实现了接口中定义的方法,他是一种可重入锁,除了能完
成 synchronized 所能完成的所有工作外,还提供了诸如可响应中断锁、可轮询锁请求、定时锁等避免多线程死锁的方法。
PS:ReentantLock和Synchronized相比是锁可中断,可加多个锁,实现公平锁。
6.Semaphore(信号量)
Semaphore semaphore = new Semaphore(int permits , boolean isFair)
在业务代码使用时表示最多能有permits个线程同时处理,并且能实现是否为公平锁isFair
7.AtomicXXX(原子操作)
提供对XXX对象的原子操作
8.可重入锁(递归锁)
可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。
在 JAVA 环境下 ReentrantLock 和 synchronized 都是可重入锁。
9.公平锁与非公平锁
a.公平锁:加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得(率先请求锁资源的线程先获取锁)
b.非公平锁:加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待
10.ReadWriteLock(读写锁)
a.Java并发库中ReetrantReadWriteLock实现了ReadWriteLock接口并添加了可重入的特性
b.ReetrantReadWriteLock读写锁的效率明显高于synchronized关键字
c.ReetrantReadWriteLock读写锁的实现中,读锁使用共享模式;写锁使用独占模式,
换句话说,读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的
d.ReetrantReadWriteLock读写锁的实现中,需要注意的,当有读锁时,写锁就不能获得(锁升级);
而当有写锁时,除了获得写锁的这个线程可以获得读锁外(锁降级),其他线程不能获得读锁