看下这个接口有几个方法等着我们重写
六个方法 加锁,尝试加锁,定时尝试加锁,解锁 主要是这是个方法 其他两个骚方法放一边 不玩这么骚的
创建一个类 我这里取名叫 MyReentrantLock 我的可重入锁 实现 lock接口
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* @author sz
* @DATE 2022/3/16 20:30
*/
public class MyReentrantLock implements Lock {
@Override
public void lock() {
}
@Override
public void unlock() {
}
@Override
public boolean tryLock() {
return false;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public Condition newCondition() {
return null;
}
}
我们先来看下JUC包的下锁都是怎么实现的
调用 ReentrantLock().lock()方法 发现走的是 sync.lock() sync是什么呢 ? 点一下
哦 原来是继承了 AbstractQueuedSynchronizer 的一个 静态抽象内部类
AbstractQueuedSynchronizer 又是什么 点进去再看一下
算了 2000多行代码 简单说一下吧 AbstractQueuedSynchronizer 简称 AQS 也就是大名鼎鼎的 抽象队列同步器
没听过 ? 不知道抽象队列同步器? 简单说下就是一个框架 用来做同步器也就是锁的框架 具体的百度一下
从上面那个动图也可以看到 最后走到了 AbstractQueuedSynchronizer 里面 调用 unsafe的 compareAndSwapInt () 方法 也就是乐观锁的实现
unsafe类又是啥 看名字 不安全的类 操作底层的 调用compareAndSwapInt 方法 要传四个参数
第一个参数时你要操作的对象 第二个参数是属性的偏移量 第三个是期望值 第四个是要修改的值
怎么获取 属性的偏移量呢 ? 看看源码是怎么写的
stateOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("state"));
哦 原来是调用 unsafe.objectFieldOffset()
我们也来试试获取一下偏移量
先尝试创建 unsafe 对象
new unsafe 咦 不对劲,不能new 看下构造方法 ,好家伙 私有的 在看看有没有静态方法能返回unsafe对象
找到了
Unsafe.getUnsafe()
返回一个 unsafe对象 打印输出一下
咦,报错了 什么意思
Exception in thread "main" java.lang.SecurityException: Unsafe
权限异常 不安全?
在看看这个 getUnsafe 方法
什么意思 获取类加载判断是不是 isSystemDomainLoader
点进去看一下
null ? null 是什么
JVM将类加载进内存有三个内加载器 不熟悉的可以去看看我之前的帖子 JAVA虚拟机上篇 之 JVM的组成和类的加载过程 一次给你搞明白_秋日的晚霞的博客-CSDN博客
其中最顶层的 BootStrapClassLoader 类加载器就是 null 也就说这个类 只能由 JVM创建 我们不能创建对象 那怎么办
冥思苦想 … 嗯 试试反射
public static Unsafe getUnsafe() throws Exception {
//利用反射
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true); // 设置为可见
Unsafe unsafe = (Unsafe) theUnsafe.get(null); // 获取Unsafe对象
return unsafe;
}
惊喜的发现创建成功了 到此 自己创建锁的第一步已经实现了