AQS:
LockSupport:AQS 的底层支持
JUC-->AQS-->LockSupport
1.可重入锁:(递归锁)
java.util.concurrent,atomic.Lock;
ReentrLock;
复制代码
可重入锁--是指,同一个线程获取到外层的锁对象之后,如果内层方法中的锁对象和外层的一致,可自动进入的一个过程;(不会因为之前已经拥有锁未释放,就阻塞)
一般锁的逻辑是,对于将要改变的数据,进行细节过程化分,
2.解析锁的使用过程:
首先两个对象去,直接去家里,a 先去获取到钥匙,直接进入,但是这里原子性的操作,当 A 获取到锁对象时候,B 只能在外面等,等到 A 对象将锁(释放了之后,意思是解锁了以后,)、B 对象才可以使用,这既是一个简单地锁对象的过程;从抢占--->释放的过程;一个线程中多个流程可以获取同一把锁,持有这把同步锁可以再次进入;
3.可重入锁的分类:
隐式锁:synchronized,基于 JVM 层面的,对于锁对象,都是隐藏起来的,加锁和解锁;
显示锁:以 Lock 的实现类,ReentrantLock ,(可以自由的加锁和释放锁,也是比较好的操作性更好;) ReentrantLock
package java.util.concurrent.locks;
public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
/** Synchronizer providing all implementation mechanics */
private final Sync sync;
复制代码
证明 Synchronzied 是一个可重入锁:
package com.atguowang.thirdinterview.juc;
/**
* @author webstart
* @time 2020/10/26/10:41
* @description synchronized中对于可重入锁的验证
**/
public class TestSyn {
//老伙计-线程操作资源类
static Object dataTest=new Object();
//
static void m1(){
new Thread(()->{
synchronized (dataTest){ System.out.println(Thread.currentThread().getName()+"\t"+"外层区域"); }
synchronized (dataTest){ System.out.println(Thread.currentThread().getName()+"\t"+"中层区域");}
synchronized (dataTest){ System.out.println(Thread.currentThread().getName()+"\t"+"中层区域");}
},"lucas").start();
}
public static void main(String[] args) {
m1();
}
}
复制代码
同步方法的展示:
package com.atguowang.thirdinterview.juc;
/**
* @author webstart
* @time 2020/10/26/10:41
* @description synchronized中对于可重入锁的验证:同步方法
**/
public class TestSyn2 {
public synchronized void m1(){
//打印
System.out.println("外");
m2();
}
public synchronized void m2(){
//打印
System.out.println("中");
m3();
}
public synchronized void m3(){
//打印
System.out.println("内");
}
public static void main(String[] args){
new TestSyn2().m1();
};
}
复制代码
使用字节码文件去查看 synchronized 的运行过程;
ReentrantLock 的显示的可重入锁的工作原理:
特别注意:
如果说,加锁的次数和,解锁的次数都是不匹配的,就会导致,当前线程结束后,我们无法获取到锁对象,导致死锁,数据请求失败等问题;
评论