一图流讲解并发(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 条评论
 下一页
  
   
   
   
   
  
  
  
  
  
  
  
  
 