一图流讲解并发(Synchronized、Volatile、CAS、AQS、并发集合、线程池)
2020-05-18 14:00:35 0 举报
synchronized一图流讲解
作者其他创作
大纲/内容
false
返回node
true,加了state
state一个state管理所有线程
true
state=0
CAS->state
非公平锁lock()
true,就返回false
失败了
CLH
非公平锁
tail == null
方法放大
公平锁
就是判断waitStatus;等于-1;return true;如果ws>0;判断前节点的ws,如果前节点ws>0;
通过failed判断是否失败了
acquire
自旋1:final Node p = node.predecessor();//获取前节点2: 2.1:如果前节点是head;span style=\"font-size: inherit;\
shouldParkAfterFailedAcquire
1.compareAndSetHead(new Node());//头节点放个node,但是这个node里面是空的2.tail = head;//尾节点也是个空节点
current == getExclusiveOwnerThread()
cancelAcquire
占用线程1
Synchronized,可以用来修饰代码块,也可以用来修饰方法,通过反编译可以看到其根本原理就是monitor enter和monitor exit来控制的,monitor也有计数器,当为0的时候执行monitor enter,不为0时候等待,进入了+1,离开-1,java被加载到jvm中的,每一个对象实例都包含了对象头、实例数据、对齐填充,其中对象头中有一部分数据叫做mark word,它是一个32位的存储单元,其中就存储了对应monitor的标识与对应的锁状态。在jdk6之后,Synchronized有了优化,偏向锁,轻量级锁... ...偏向锁:当锁对象第一次被线程A获取时,虚拟机将会把对象头中的标志位设为可偏向,是否偏向锁置为1,锁对象与线程A绑定偏向锁,当下一次A线程再参与竞争时,对象偏向被线程A锁住;轻量级锁:就是自旋锁+CAS;CAS尝试修改对象头的markword中心的信息,那么自旋又是什么意思呢,就是在许多场景下,需要加锁执行的代码是执行很快的,那么我只需要线程死循环一会来获取锁就可以避免阻塞了,JDK6中叫适应性自旋锁,怎么适应性呢,就是死循环的次数是由上一次线程获取锁时自旋的次数。
addWaiter
tryAcquire
parkAndCheckInterrupt
等待线程2
volatile的原理就是内存屏障,它具备两个意义:1.可见性:变量的值在线程之间的传递需要通过住内存完成。2.禁止重排序:JVM会利用cpu的特性,在不影响结果的情况下,有可能会把后面的代码先执行了,这就是重排序,用volatile修饰的变量被禁止了指令重排序;比如线程1做了两件事,初始化对象,改变一个控制线程2开关的变量,然后线程2,对这个对象做一件事情,假如开关被重排序了,先打开但是没初始化对象,那线程2就会报错;这个例子只是说明下指令重排序。但是volatile并不能保证原子性,比如AB两个线程操作i++,A线程先操作i之后会写到主内存之前,如果B线程也操作,就不能保证原子性。
hasQueuedPredecessors();非公平锁不进
acquireQueued
核心源码
acquire(1);
CAS
tryAcquire(实现类自己实现去)
selfInterrupt()
等待线程3
LockSupport.park(this);//挂起
head(head节点就是new Nod();里面没有实际要操作的线程)
cas插入node
等待线程4
tail
tail != null;
公平锁lock()
enq
setExclusiveOwnerThread(Thread.currentThread());
结束
0 条评论
回复 删除
下一页