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}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章