Java-技术专题-AQS和Volatile和Synchronized实现原理

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"本文参考:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://links.jianshu.com/go?to=https%3A%2F%2Fblog.csdn.net%2Fu010670411%2Farticle%2Fdetails%2F87921138","title":null},"content":[{"type":"text","text":"JUC学习(八):AQS的CLH队列"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.jianshu.com/p/4682a6b0802d","title":null},"content":[{"type":"text","text":"并发编程——详解 AQS CLH 锁"}]},{"type":"link","attrs":{"href":"https://www.jianshu.com/p/8a58d8335270","title":null},"content":[{"type":"text","text":"JMM和底层实现原理"}]}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"AQS"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" "},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"ReentrantLock类关于lock接口的操作都交给了内部类Sync类来实现,Sync类又有两个子类"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#9254DE","name":"purple"}},{"type":"strong"}],"text":"NonFairSync,FairSync"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":",公平锁和不公平锁;"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"abstract static class Sync extends AbstractQueuedSynchronizer\n static final class NonfairSync extends Sync\n\tstatic final class FairSync extends Sync"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"AQS重要成员变量"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" private transient volatile Node tail; // CLH队列\n private volatile int state; // 锁的状态"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"AQS使用的设计模式:"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" "},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"模板方法设计模式:"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"定义一个代码模板结构,相同部分在父类实现,不同部分由子类实现"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"link","attrs":{"href":"https://links.jianshu.com/go?to=https%3A%2F%2Fblog.csdn.net%2Fcarson_ho%2Farticle%2Fdetails%2F54910518%3Futm_medium%3Ddistribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase%26depth_1-utm_source%3Ddistribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase","title":null},"content":[{"type":"text","text":"模板方法模式(Template Method) - 最易懂的设计模式解析"}]},{"type":"text","marks":[{"type":"strong"}],"text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" 安卓中的View,Activity都使用了模板方法设计模式,View类规范了所有View需要实现的行为,View的子类可以在"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"onMeasure"},{"type":"text","marks":[{"type":"strong"}],"text":","},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"onLayout,onDraw"},{"type":"text","marks":[{"type":"strong"}],"text":"中扩展各自不同的行为;体现了设计模式的"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong"}],"text":"开闭原则"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":"AQS抽象类为子类提供了"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"tryAcquire"},{"type":"text","marks":[{"type":"strong"}],"text":","},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"tryRelease"},{"type":"text","marks":[{"type":"strong"}],"text":"去扩展自己的不同行为"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"NonfairSync:"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"NonfairSync.lock()"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"final void lock() {\n if (compareAndSetState(0, 1))\n setExclusiveOwnerThread(Thread.currentThread());\n else\n acquire(1);\n}\n\nprotected final boolean compareAndSetState(int expect, int update) {\n // See below for intrinsics setup to support this\n return unsafe.compareAndSwapInt(this, stateOffset, expect, update);\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" 首先通过CAS尝试将AQS的state由0变为1,如果成功,说明当前锁没有被线程持有,调用setExclusiveOwnerThread()设置当前线程持有当前锁即可;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 如果失败了说明当前锁被持有,调用acquire(1);"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"acquire()"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" public final void acquire(int arg) {\n if (!tryAcquire(arg) &&\n acquireQueued(addWaiter(Node.EXCLUSIVE), arg))\n selfInterrupt();\n }"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在acquire()中,首先调用了tryAcquire()尝试获取"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"NonFairSync的tryAcquire的实现"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" final boolean nonfairTryAcquire(int acquires) {\n final Thread current = Thread.currentThread();\n int c = getState();\n if (c == 0) {\n if (compareAndSetState(0, acquires)) {\n setExclusiveOwnerThread(current);\n return true;\n }\n }\n else if (current == getExclusiveOwnerThread()) {\n int nextc = c + acquires;\n if (nextc < 0) // overflow\n throw new Error(\"Maximum lock count exceeded\");\n setState(nextc);\n return true;\n }\n return false;\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule"},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 首先判断AQS的"},{"type":"text","marks":[{"type":"strong"}],"text":"state"},{"type":"text","text":"是否为"},{"type":"text","marks":[{"type":"strong"}],"text":"0"},{"type":"text","text":",如果是"},{"type":"text","marks":[{"type":"strong"}],"text":"0"},{"type":"text","text":",则当前锁未被持有,设置当前线程即可,如果不为0,说明当前锁被持有,并且有另一个线程尝试进入,则将AQS的"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"state+1"},{"type":"text","text":"(类似"},{"type":"text","marks":[{"type":"strong"}],"text":"synchronized"},{"type":"text","text":"的"},{"type":"text","marks":[{"type":"strong"}],"text":"monitor"},{"type":"text","text":"的进入数);"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"addWaiter()"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" private Node addWaiter(Node mode) {\n Node node = new Node(Thread.currentThread(), mode);\n // Try the fast path of enq; backup to full enq on failure\n Node pred = tail;\n if (pred != null) {\n node.prev = pred;\n if (compareAndSetTail(pred, node)) {\n pred.next = node;\n return node;\n }\n }\n enq(node);\n return node;\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"strong"}],"text":"addWaiter"},{"type":"text","text":"的作用是将为"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"获得锁被阻塞的线程打包成Node添加到tail链表(队列)中保存起来"},{"type":"text","text":",添加链表节点的过程使用了CAS添加;"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/be/be1156567ac4e731da5c0ff12d7eace2.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":8,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UnFairSync lock"}]},{"type":"paragraph","attrs":{"indent":8,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":" 回顾一下UnFairSync的lock()过程:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"首先尝试通过CAS将锁的状态(AQS的state)由0变为1;如果成功说明锁未被持有,设置当前线程持有即可,如果失败,说明锁已经被持有,调用acquire(1);在acquire()中,"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"1"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"首先调用tryAcquire()再次尝试获取锁,如果失败将锁的state+1,"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"2"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"其次调用addWaiter()将当前线程包装成Node放入等待队列"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"AQS的tail"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"中,"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"3"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"调用当线程的interrupt()尝试中断;"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"unLock():"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" public void unlock() {\n sync.release(1);\n }\n\n public final boolean release(int arg) {\n if (tryRelease(arg)) {\n Node h = head;\n if (h != null && h.waitStatus != 0)\n unparkSuccessor(h);\n return true;\n }\n return false;\n }\n\n protected final boolean tryRelease(int releases) {\n int c = getState() - releases;\n if (Thread.currentThread() != getExclusiveOwnerThread())\n throw new IllegalMonitorStateException();\n boolean free = false;\n if (c == 0) {\n free = true;\n setExclusiveOwnerThread(null);\n }\n setState(c);\n return free;\n }\n"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"unLock()做的事情:将锁的state-1,如果state==0了,在等待队列中唤醒一个线程;"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"公平锁和不公平锁的区别:"}]}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"FairLock.lock()"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" final void lock() {\n acquire(1);\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"公平锁的lock方法是直接调用acquire();"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"tryAcquire的实现:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" /**\n * Performs non-fair tryLock. tryAcquire is implemented in\n * subclasses, but both need nonfair try for trylock method.\n */\n final boolean nonfairTryAcquire(int acquires) {\n final Thread current = Thread.currentThread();\n int c = getState();\n if (c == 0) {\n if (compareAndSetState(0, acquires)) {\n setExclusiveOwnerThread(current);\n return true;\n }\n }\n else if (current == getExclusiveOwnerThread()) {\n int nextc = c + acquires;\n if (nextc < 0) // overflow\n throw new Error(\"Maximum lock count exceeded\");\n setState(nextc);\n return true;\n }\n return false;\n }\n /**\n * Fair version of tryAcquire. Don't grant access unless\n * recursive call or no waiters or is first.\n */\n protected final boolean tryAcquire(int acquires) {\n final Thread current = Thread.currentThread();\n int c = getState();\n if (c == 0) {\n if (!hasQueuedPredecessors() &&\n compareAndSetState(0, acquires)) {\n setExclusiveOwnerThread(current);\n return true;\n }\n }\n else if (current == getExclusiveOwnerThread()) {\n int nextc = c + acquires;\n if (nextc < 0)\n throw new Error(\"Maximum lock count exceeded\");\n setState(nextc);\n return true;\n }\n return false;\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"在调用tryAcquire()尝试获取锁时,公平和不公平锁的实现稍微不同,公平锁会在state == 0的时候直接设置当前线程去持有锁,而非公平锁会调用"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"hasQueuedPredecessors()"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"去判断tail等待队列中有没有比当前线程等待时间更长的线程,如果有,就不会设置当前线程去持有锁;"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"AQS内部的CLH自旋锁"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":" CLH是一个基于链表(队列)的自旋(公平)锁,每一个等待锁的线程封装成节点,不断自旋判断前一个节点的状态,如果前一个节点释放锁就结束自旋;"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"AQS"},{"type":"text","text":"的"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"CLH"},{"type":"text","text":"队列"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"tail"}]},{"type":"text","text":"对"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"CLH"},{"type":"text","text":"自旋锁进行了两个方面改进:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"节点的结构:"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#BAE7A1","name":"green"}},{"type":"strong"}],"text":"AQS中的CLH队列的节点采用双向链表"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"节点等待机制:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#BAE7A1","name":"green"}},{"type":"strong"}],"text":"传统的CLH是通过不断自旋判断前一个节点的状态,AQS改成了自旋+阻塞+唤醒,"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"线程在经过几次自旋后会进入阻塞状态等待唤醒,唤醒后继续自旋,等待前一个线程释放锁,兼顾了"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"性能和效率;"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"可重入锁的实现:"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"可重入锁:指任意线程在获取到锁之后能够再次获取该锁而不会被锁所阻塞"}]}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#BAE7A1","name":"green"}},{"type":"strong"}],"text":"在 tryAcquire()中判断是否是当前线程持有,如果是则将state通过CAS +1;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#BAE7A1","name":"green"}},{"type":"strong"}],"text":"在释放锁时,只有state为0时,锁才会正真释放,可以被其他线程持有;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"JMM ("},{"type":"codeinline","content":[{"type":"text","text":"JAVA Memory Model"}]},{"type":"text","text":")"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong"}],"text":" "},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"JVM定义了JMM用来屏蔽各种硬件和操作系统的内存访问差异,即JMM的主要目标定义程序中各个变量访问规则;"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/06/06ce58d48591039a0237fa44d5fc0c58.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":" JMM规定了所有的变量都存放在主内存,每个线程有自己的工作内存,工作内存中保存着主内存变量的副本,线程对变量的访问只能通过自己的工作内存的副本访问,每个线程只能访问自己的工作线程;"}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"内存间交互操作:"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JMM定义了8种原子操作用来实现"},{"type":"text","marks":[{"type":"strong"}],"text":"主内存到工作内存的拷贝"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"工作内存到主内存的同步"},{"type":"text","text":":"}]},{"type":"horizontalrule"},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"lock锁定:"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"作用于主内存 ,将主内存的一个变量标识为一个线程独占"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"unlock解锁:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"作用于主内存,把主内存中一个处于被线程独占的变量释放出来"}]}]}]},{"type":"horizontalrule"},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"read读取:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"作用于主内存,把主内存的变量传入到工作内存,配合load使用"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"load载入:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"作用于工作内存,配合read将主内存的值放入工作内存的副本中"}]}]}]},{"type":"horizontalrule"},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"use使用:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"作用于工作内存,当虚拟机遇到一个需要使用这个变量的字节码指令时,将工作内存变量的值传递给执行引擎。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"assign赋值:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"作用于工作内存,当虚拟机遇到一个需要给变量赋值的字节码指令时,从执行引擎接收新的值传入工作内存。"}]}]}]},{"type":"horizontalrule"},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"store存储:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"作用于工作内存,将工作内存的一个变量传递给主内存,配合write使用"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"write写入:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"作用于主内存,配合store将工作内存副本的值在主内存更新"}]}]}]},{"type":"horizontalrule"},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Volatile:"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"被"},{"type":"text","marks":[{"type":"strong"}],"text":"volatile"},{"type":"text","text":"修饰的变量具有"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"可见性,有序性"}]},{"type":"text","text":","},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"保证单个变量的读写的"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"原子性"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}]},{"type":"text","text":"(i++不保证)"}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"volatile原理:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"被volatile修饰的变量会存在一个"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"lock前缀"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":",lock前缀的作用是将当前线程的工作内存中副本值直接写入主内存,并且将其他工作内存的值失效(立刻执行store,write操作)"},{"type":"text","text":";"},{"type":"text","marks":[{"type":"strong"}],"text":"强制刷新变量,保证可见性;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"lock前缀还有一个功能:"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"内存屏障"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"(重排序不能在内存屏障前执行),抑制重排序,保证有序性;"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"happen-before:先行发生原则"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":" 如果操作1 happen-before 操作2,那么操作1的结果对操作2 是可见的 仅要求可见性,不要求有序性,可以重排序;"}]},{"type":"blockquote","content":[{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"volatile规定了变量的写 happen-before 变量的读"},{"type":"text","text":";"}]}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"synchronized原理:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 每一个对象都会有一个"},{"type":"text","marks":[{"type":"strong"}],"text":"monitor"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"monitor"},{"type":"text","text":"是由C++实现的一个ObjectMonitor类,可以理解为一个实现线程同步的对象;"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a3/a3b81e2b65f344b08d1b05c0be0b8150.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Monitor的属性"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":" "},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"当多个线程同时访问同步代码块时,会先将线程放入"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"EntryList"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"中,当一个线程持有monitor对象 "}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":" 后,会"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"count++"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":",设置"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"owner"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"为此线程;"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":" 如果"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"owner"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"调用wait()或者同步任务完成,就会将"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"count--"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":","},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"owner"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"设置为null,并且将这个线程 "}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":" 放入"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"WaitSet"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":",等待下一次被唤醒"}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"monitorenter:"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 遇到"},{"type":"text","marks":[{"type":"strong"}],"text":"monitorenter"},{"type":"text","text":"指令会尝试获取"},{"type":"text","marks":[{"type":"strong"}],"text":"monitor"},{"type":"text","text":"对象,通过判断"},{"type":"text","marks":[{"type":"strong"}],"text":"monitor"},{"type":"text","text":"对象的"},{"type":"text","marks":[{"type":"strong"}],"text":"count"},{"type":"text","text":"是否为"},{"type":"text","marks":[{"type":"strong"}],"text":"0"},{"type":"text","text":",如果"},{"type":"text","marks":[{"type":"strong"}],"text":"count = 0"},{"type":"text","text":",当前线程就持有锁,"},{"type":"text","marks":[{"type":"strong"}],"text":"count++"},{"type":"text","text":",如果不会零,就阻塞,如果持有锁的线程重新进入锁,count继续++;"}]}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"monitorexit:"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 执行exit指令的线程必须是锁的持有者,执行完exit后,monitor的count--,如果count == 0,则退出锁,被阻塞的线程可以尝试获取锁;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 同步代码块时通过enter/exit字节码指令实现的,如果是同步方法,就会在方法的字节码加入一个"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"ACC_SYNCHRONIZED"}]},{"type":"text","text":"的flag,如果有这个flag,表明这是一个同步方法"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":",线程在执行时会尝试获取Monitor对象(静态方法是类的Monitor,非静态方法则是实例对象的Monitor),本质上和enter、exit一样都是通过Monitor对象来实现的;"}]}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"synchronized优化:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"在早期的版本中,使用synchronized关键字加锁都会将拿不到锁的线程进行阻塞,需要上下文切换,效率较低,在jdk1.6以后对synchronized锁进行了优化;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}}],"text":"锁消除:"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}}],"text":"在代码上加了锁,但是虚拟机判断出这一块代码不可能被多线程竞争,就会把这个锁消除掉;虚拟机判断的依据是"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"逃逸分析"}]}]}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"逃逸分析:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"分析对象的动态作用域,当一个对象在方法中被定义后,它可能被外部其他方法访问(作为参数传入),这种称为方法逃逸,如果被其他线程访问,称为线程逃逸,如果能证明这个对象不会逃逸到其他方法或者线程,虚拟机会对它做一些优化:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"栈上分配:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"对象的内存存放在栈帧中而不是堆上"},{"type":"text","text":";"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"同步消除:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong"}],"text":"锁消除"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"标量替换:"},{"type":"text","text":" "},{"type":"text","marks":[{"type":"strong"}],"text":"标量:"},{"type":"text","text":"一个数据无法分解成更小的数据,比如java原始类型;"},{"type":"text","marks":[{"type":"italic"},{"type":"strong"}],"text":"聚合量:"},{"type":"text","text":"可以被分解成更小的数据,比如对象;如果逃逸分析证明这个对象不会方法逃逸,并且这个对象是聚合量,那么程序执行的时候可能不会创建这个对象,而是创建它的成员变量;"}]}]}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"锁粗化:"}]},{"type":"text","text":"如果虚拟机检测到一串操作都对一个对象加锁,释放锁,将会把加锁的范围粗化到整个操作的外部;"}]}]}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"\t\tStringBuffer stringBuffer = new StringBuffer();\n stringBuffer.append(\"加锁----释放锁\");\n stringBuffer.append(\"加锁----释放锁\");\n stringBuffer.append(\"加锁----释放锁\");\n \n @Override\n public synchronized StringBuffer append(String str) {\n toStringCache = null;\n super.append(str);\n return this;\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面的操作就会进行synchronized锁粗化的优化"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"自适应自旋:"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FFBEBF","name":"pink"}},{"type":"strong"}],"text":"自旋时间由前一次在同一个锁的自旋时间和锁的拥有者状态来决定,如果虚拟机判断获得这个锁的可能性很大,就会增加自旋时间,如果觉得很难获得锁,可能会省去自旋这一步节约CPU;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"偏向锁:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FFBEBF","name":"pink"}},{"type":"strong"}],"text":"这个锁会偏向于第一个持有它的线程,如果在运行过程中,同步锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,减少加锁/解锁的一些CAS操作(比如等待队列的一些CAS操作),这种情况下,就会给线程加一个偏向锁。 如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会消除它身上的偏向锁,将锁恢复到标准的轻量级锁;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}],"text":"轻量级锁:"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FDED8A","name":"yellow"}},{"type":"strong"}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FFBEBF","name":"pink"}},{"type":"strong"}],"text":"由偏向锁转化来,相对于传统的重量级锁,不会阻塞线程,而是通过自旋进行等待;以CPU为代价,避免线程的上下文切换,追求响应速度;"},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FFBEBF","name":"pink"}},{"type":"strong"}],"text":"偏向锁切换到轻量级锁会Stop the World"}],"marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"bgcolor","attrs":{"color":"#FFBEBF","name":"pink"}},{"type":"strong"}]}]}]}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f4/f4f137a424c74b9313170d5fe17537eb.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章