> 文章列表 > 锁简单介绍

锁简单介绍

锁简单介绍

锁简单介绍

文章目录

  • 1. ReentrantLock 可重入锁
  • 2. 不可重复锁,需要自定义
  • 3. 悲观锁:对数据上锁,其他线程拿不到锁,就不能阻塞了
  • 4. 乐观锁
  • 5. 独占锁(排他锁)
  • 6. 共享锁
  • 7. 互斥锁
  • 8. ReentrantReadWriteLock 读写锁
  • 9. 公平
  • 10. 非公平锁
  • 11. 自旋锁
  • 12. 分段锁
  • 13.锁升级
  • 14. 锁粗化
  • 15. 锁清除

1. ReentrantLock 可重入锁

可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁
synchronized和ReentrantLock都是可重入锁

Lock lock = new ReentrantLock();
lock.lock();
lock.unlock();

2. 不可重复锁,需要自定义

package com.xin.demo.threaddemo;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;public class LockDemo2UnReentrantLock {public static void main(String[] args) {MyLock lock = new MyLock();lock.lock();try {System.out.println("第一次获取锁");lock.lock();try {System.out.println("第二次获取锁");} finally {lock.unlock();}} finally {lock.unlock();}}
}class MyLock implements Lock {//绑定线程private Thread thread;@Overridepublic void lock() {synchronized (this) {while (thread != null) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}this.thread = Thread.currentThread();}}@Overridepublic void lockInterruptibly() throws InterruptedException {}@Overridepublic boolean tryLock() {return false;}@Overridepublic boolean tryLock(long l, TimeUnit timeUnit) throws InterruptedException {return false;}@Overridepublic void unlock() {synchronized (this) {if (thread != Thread.currentThread()) {return;}thread = null;notifyAll();}}@Overridepublic Condition newCondition() {return null;}
}

锁简单介绍

3. 悲观锁:对数据上锁,其他线程拿不到锁,就不能阻塞了

synchronized RetrantLock HashTable 都是悲观锁

4. 乐观锁

加字段version

5. 独占锁(排他锁)

一个线程对共享数据上锁后,其他线程就不能对读共享数据加任何类型的锁,synchronized和lock的实现都是独占锁
ReentrantReadWriteLock.writeLock()是独占锁

ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
writeLock.lock();
writeLock.unlock();

6. 共享锁

多个线程同时对共享数据加锁,且对共享数据加的锁只能都是共享锁,不能是独占锁,共享锁只能读数据,不能修改数据
ReentrantReadWriteLock.readLock()是共享锁

ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
readLock.lock();
readLock.unlock();

读锁->写锁:锁升级
写锁->读锁:锁降级

7. 互斥锁

互斥锁是独占锁的一种常规实现,读读、读写、写写都是互斥的

8. ReentrantReadWriteLock 读写锁

写线程独占写锁,读线程共享读锁,允许一个写锁和多个读锁共存

9. 公平锁

公平锁按照线程申请锁的顺序来获取锁

ReentrantLock reentrantLock = new ReentrantLock(true);
public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}

10. 非公平锁

不是按照线程申请的顺序来获取锁,可能造成优先级翻转
synchronized 是非公平锁,ReentrantLock默认也是非公平锁

11. 自旋锁

  • 线程没有获得锁的情况下,不是直接挂起,而是进行忙循环,这个忙循环就是自旋
  • 自适应自旋:即自旋自适应,以为不可能让线程一直自旋,需要一个自旋的时间,这个时候就可以根据上一次自旋的时间来决定这次自旋的时间。
  • 自旋是为了有效防止线程做状态的转换,因为线程挂起和唤醒也很消耗性能,AtomicInteger中就有自旋的操作

12. 分段锁

对锁的粒度进一步优化,操作数组时不是对整个数组加锁,仅仅针对其中的一项加锁
ConcurrentHashMap就使用了分段锁

13.锁升级

无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁,根据所线程的竞争情况逐渐升级,synchronized就有锁升级的过程
偏向锁:锁偏向于第一个获取锁的线程
轻量级锁:线程会自旋
重量级锁:排他锁,其他线程直接阻塞

14. 锁粗化

多次上锁解锁的请求合并为一次

15. 锁清除

没有竞争的锁,直接清除