单体架构中数据安全问题:
1 数据安全的问题。 2 AQS的原理。 3 lock 是如何实现线程的阻塞和唤醒
ReentrantLock 原理 (独占锁)
AQS abstractQueuedSynchronizer 是解决并发场景下的数据的安全问题。
lock 锁的使用:
公平锁: 公平锁和非公平锁的对列都是基于锁内部维护的一个双向链表,表结点node的值就是每一个请求当前锁的线程,公平锁就是每次都是依次获取队首取值。 非公平锁就是随机获取新的线程的锁 有很大的几率直接获取锁。
设置公平锁就在ReentrantLock(true)
设置非公平锁就在ReentrantLock(false)
数据安全的问题产生的原因是什么:
可见性:
JMM java的内存模型 解决的方式: volatile synchrionized lock
有序性:
指令重新排序 volatile synchrionized lock
原子性:
保证多个操作要么执行, 要么都不执行 synchrionized lock atomiclnteger
使用 Lock 来实现:
特性有互斥 可重入 (在一个线程lock锁中在加一个lock锁)
重入锁 就是防止死锁
lock.lock(); 加锁
lock.unlock(); 释放锁
lockSupport.park(this); 是锁定当前的线程
lockSupport.unpark(Thread t); 唤醒指定的线程
非公平锁:是线程都抢
公平锁:是先进来 先获取 后进来就后获取
lock 设置状态
在线程中开启锁的是 初始状态给state 设置为0 , 是利用java unsafe 直接操作内存的值 设置为1 绕过了jmm的控制。
没有抢到锁线程存储:
没有抢到锁的线程都添加到双向链表中。
存储把当前的线程变成了一个对象, 是双向链表的结构。head 节点指向了初始节点, tail(尾结点) 节点指向 第一个线程节点。
阻塞:
就是删除了链表中 状态值大于0的线程 ,就是加入的节点进行遍历找出来把初始状态0 设置成-1 。