最近在做公司业务的时候, 使用到了隐式的锁,synchronize , 其实就是jvm 多了一个montior 的监视器,
我们先写一个代码

运行一下,生成class文件,再用 Javap -v 打印所有的字节码信息。


monitorenter 开始监视,monitorexit 监视退出, 为啥有两个啊。
一个正常退出,一个不正常退出。这是synchronize 隐式锁的原理,现在我们来说说一下lock , 底层就是cas 原理,在加上一个队列。
我们要自己写一个锁,要实现lock, unlock 的方法, 线程之间要显示的通讯,这里我们用LockSupport, 进行阻塞,唤醒等

底层是unsafe 直接操作字节码的,本地方法的。先说一下设计思路啊
AtomicReference 类,来作为对象的原子引用,在用linkedBlockingQueue 队列存放阻塞的线程, 加锁的实现,先 获取当前线程,进行cas 看一下是否成功,进行死循环, 不成功,先阻塞,把其他的线程加入队列
等到不阻塞的时候,在把队列的线程给释放了。防止内存泄漏。
解锁就是遍历队列,唤醒所有阻塞的线程, 这里唤醒所有的默认是非公平的,不一定排在最前的就能获得锁
现在我们来开始写代码,先实现lock


这里没有指定队列的大小,因为add 的时候默认的 就是integer.max
我们写一个代码测试一下,先测试不加锁和加锁的代码
public static int count = 0;
public static void increase() {
count++;
}
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[20];
for (int i = 0; i < 20; i++) {
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
increase();
}
}
});
threads[i].start();
}
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println(count);
}运行结果 ,正确结果应该是20000,

这说明并发,没有保障原子性。加上我们自己写锁

