锁的概念
因为操作系统是分片运行的,当一段公有数据在一个分片段同时被多个线程访问就换涉及到数据安全问题,因为此操作是非原子性的。锁就是用了解决这一数据不安全问题的,它的作业是保证这一时间段的操作是原子性的,从而保证数据的安全。
java的synchronized
java的synchronized是系统提供的一个关键字,可用来修饰方法和代码块,被修饰的代码在多线程的情况下会对该区域代码上锁,保证代码执行的原子性。
synchronized锁升级
无锁,即没有给对象上锁。
偏向锁,对象偏向于某一个线程上的锁。
轻量级锁,一种不惊动操作系统的在java层级定义且能保证原子性的锁。
重量级锁,需要惊动操作系统的,且需要调用用户态->内核态的锁(需消耗更多资源)
java对象锁的信息
java对象锁的信息存放在对象的makeword中
001 表示无锁 (对象正常初始化的标志)
101 表示偏向锁 (Thread.sleep(4000) 左右会启动偏向锁 也可以设置jvm参数来设置默认初始化启动偏向锁 偏向锁是不会释放的 即代码块结束 对象头不变 对象头里会记录线程ID 有点类似于局部性原理)
000 轻量级锁 (两个线程的时候就会升级到轻量级锁 因为线程ID不一样)
010 重量级锁 (资源长时间被一个线程占用的时候升级 )
ReentrantLock 锁
ReentrantLock 有可重入/不可重入两种状态的锁 在加锁的时候 如果锁已经被占用 即 state > 0 则会判断 现在占用锁的线程和当前线程是否是同一个线程 如果是 则state+1 实现锁重入。
RenntrantLock 在多线程情况下 若多个线程同时竞争锁 会维护一个队列 在维护这个队列的过程中会多次获取锁(但只有第一个线程可以自旋) 目的是尽量不让线程park休眠 park是需要惊动os的。