13张图,深入理解Synchronized

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Java并发编程系列第二篇","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":",文章风格依然是图文并茂,通俗易懂,本文带读者们由浅入深理解","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":",让读者们也能与面试官疯狂对线。","attrs":{}}]},{"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":"在并发编程中","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"一直都是元老级的角色,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Jdk 1.6","attrs":{}}],"attrs":{}},{"type":"text","text":"以前大家都称呼它为重量级锁,相对于","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"J U C","attrs":{}}],"attrs":{}},{"type":"text","text":"包提供的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Lock","attrs":{}}],"attrs":{}},{"type":"text","text":",它会显得笨重,不过随着","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Jdk 1.6","attrs":{}}],"attrs":{}},{"type":"text","text":"对","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"进行各种优化后,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"性能已经非常快了。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"内容大纲","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/13/131a6ad61551000ff108ec9a9da80417.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Synchronized使用方式","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Java","attrs":{}}],"attrs":{}},{"type":"text","text":"提供的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"同步关键字","attrs":{}},{"type":"text","text":",在多线程场景下,对共享资源代码段进行读写操作(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"必须包含写操作,光读不会有线程安全问题,因为读操作天然具备线程安全特性","attrs":{}},{"type":"text","text":"),可能会出现线程安全问题,我们可以使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"锁定共享资源代码段,达到","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"互斥","attrs":{}},{"type":"text","text":"(","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mutualexclusion","attrs":{}}],"attrs":{}},{"type":"text","text":")效果,保证线程安全。","attrs":{}}]},{"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":"共享资源代码段又称为","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"临界区","attrs":{}},{"type":"text","text":"(","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"critical section","attrs":{}}],"attrs":{}},{"type":"text","text":"),保证","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"临界区互斥","attrs":{}},{"type":"text","text":",是指执行","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"临界区","attrs":{}},{"type":"text","text":"(","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"critical section","attrs":{}}],"attrs":{}},{"type":"text","text":")的只能有一个线程执行,其他线程阻塞等待,达到排队效果。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6e/6e7ee8d72af4ff05b4c6d8d18d7d2fd8.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"的食用方式有三种","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"修饰普通函数,监视器锁(","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":")便是对象实例(","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"this","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":")","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"修饰静态静态函数,视器锁(","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":")便是对象的","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Class","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"实例(每个对象只有一个","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Class","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"实例)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"修饰代码块,监视器锁(","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":")是指定对象实例","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"普通函数","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"普通函数使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"的方式很简单,在","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"访问权限修饰符","attrs":{}},{"type":"text","text":"与","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"函数返回类型","attrs":{}},{"type":"text","text":"间加上","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/48/48d37b9f3d3c6de5ff062cba9e4c4ebc.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"text","text":"多线程场景下,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"thread","attrs":{}}],"attrs":{}},{"type":"text","text":"与","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"threadTwo","attrs":{}}],"attrs":{}},{"type":"text","text":"两个线程执行","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incr","attrs":{}}],"attrs":{}},{"type":"text","text":"函数,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incr","attrs":{}}],"attrs":{}},{"type":"text","text":"函数作为","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"共享资源代码段","attrs":{}},{"type":"text","text":"被多线程","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"读写操作","attrs":{}},{"type":"text","text":",我们将它称为","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"临界区","attrs":{}},{"type":"text","text":",为了保证","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"临界区互斥","attrs":{}},{"type":"text","text":",使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"修饰","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incr","attrs":{}}],"attrs":{}},{"type":"text","text":"函数即可。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"public class SyncTest {\n\n private int j = 0;\n \n /**\n * 自增方法\n */\n public synchronized void incr(){\n //临界区代码--start\n for (int i = 0; i < 10000; i++) {\n j++;\n }\n //临界区代码--end\n }\n\n public int getJ() {\n return j;\n }\n}\n\npublic class SyncMain {\n\n public static void main(String[] agrs) throws InterruptedException {\n SyncTest syncTest = new SyncTest();\n Thread thread = new Thread(() -> syncTest.incr());\n Thread threadTwo = new Thread(() -> syncTest.incr());\n thread.start();\n threadTwo.start();\n thread.join();\n threadTwo.join();\n //最终打印结果是20000,如果不使用synchronized修饰,就会导致线程安全问题,输出不确定结果\n System.out.println(syncTest.getJ());\n }\n\n}\n","attrs":{}}]},{"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":"代码十分简单,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incr","attrs":{}}],"attrs":{}},{"type":"text","text":"函数被","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"修饰,函数逻辑是对","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"j","attrs":{}}],"attrs":{}},{"type":"text","text":"进行","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"10000","attrs":{}}],"attrs":{}},{"type":"text","text":"次累加,两个线程执行","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incr","attrs":{}}],"attrs":{}},{"type":"text","text":"函数,最后输出","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"j","attrs":{}}],"attrs":{}},{"type":"text","text":"结果。","attrs":{}}]},{"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":"被","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"修饰函数我们简称","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"同步函数","attrs":{}},{"type":"text","text":",线程执行称","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"同步函数","attrs":{}},{"type":"text","text":"前,需要先获取监视器锁,简称锁,获取锁成功才能执行","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"同步函数","attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"同步函数","attrs":{}},{"type":"text","text":"执行完后,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程会释放锁并通知唤醒其他线程获取锁","attrs":{}},{"type":"text","text":",获取锁失败「","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"则阻塞并等待通知唤醒该线程重新获取锁","attrs":{}},{"type":"text","text":"」,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"同步函数","attrs":{}},{"type":"text","text":"会以","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"this","attrs":{}}],"attrs":{}},{"type":"text","text":"作为锁,即当前对象,以上面的代码段为例就是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"syncTest","attrs":{}}],"attrs":{}},{"type":"text","text":"对象。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/75/7535da7afa37df2b7e20c489e014df19.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"thread","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"执行","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"syncTest.incr()","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"前","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"thread","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"获取锁成功","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"threadTwo","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"执行","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"syncTest.incr()","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"前","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"threadTwo","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"获取锁失败","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"threadTwo","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"阻塞并等待唤醒","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"thread","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"执行完","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"syncTest.incr()","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"j","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"累积到","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"10000","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"thread","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"释放锁,通知唤醒","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"threadTwo","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程获取锁","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"threadTwo","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"获取锁成功","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"threadTwo","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"执行完","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"syncTest.incr()","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"j","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"累积到","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"20000","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"threadTwo","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"释放锁","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"静态函数","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"静态函数顾名思义,就是静态的函数,它使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"的方式与普通函数一致,唯一的区别是锁的对象不再是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"this","attrs":{}}],"attrs":{}},{"type":"text","text":",而是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Class","attrs":{}}],"attrs":{}},{"type":"text","text":"对象。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/89/89e01864c01f7b83acc80cdb08bf1570.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"text","text":"多线程执行","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"修饰静态函数代码段如下。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"public class SyncTest {\n\n private static int j = 0;\n \n /**\n * 自增方法\n */\n public static synchronized void incr(){\n //临界区代码--start\n for (int i = 0; i < 10000; i++) {\n j++;\n }\n //临界区代码--end\n }\n\n public static int getJ() {\n return j;\n }\n}\n\npublic class SyncMain {\n\n public static void main(String[] agrs) throws InterruptedException {\n Thread thread = new Thread(() -> SyncTest.incr());\n Thread threadTwo = new Thread(() -> SyncTest.incr());\n thread.start();\n threadTwo.start();\n thread.join();\n threadTwo.join();\n //最终打印结果是20000,如果不使用synchronized修饰,就会导致线程安全问题,输出不确定结果\n System.out.println(SyncTest.getJ());\n }\n\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Java","attrs":{}}],"attrs":{}},{"type":"text","text":"的静态资源可以直接通过类名调用,静态资源不属于任何实例对象,它只属于","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Class","attrs":{}}],"attrs":{}},{"type":"text","text":"对象,每个","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Class","attrs":{}}],"attrs":{}},{"type":"text","text":"在","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"J V M","attrs":{}}],"attrs":{}},{"type":"text","text":"中只有唯一的一个","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Class","attrs":{}}],"attrs":{}},{"type":"text","text":"对象,所以同步静态函数会以","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Class","attrs":{}}],"attrs":{}},{"type":"text","text":"对象作为锁,后续获取锁、释放锁流程都一致。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"代码块","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"前面介绍的普通函数与静态函数粒度都比较大,以整个函数为范围锁定,现在想把范围缩小、灵活配置,就需要使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"代码块","attrs":{}},{"type":"text","text":"了,使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"{}","attrs":{}}],"attrs":{}},{"type":"text","text":"符号定义范围给","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"修饰。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/73/7378672e9fa5d9b7984e06f64fbcdf4c.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"text","text":"下面代码中定义了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"syncDbData","attrs":{}}],"attrs":{}},{"type":"text","text":"函数,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"syncDbData","attrs":{}}],"attrs":{}},{"type":"text","text":"是一个伪同步数据的函数,耗时","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"2","attrs":{}}],"attrs":{}},{"type":"text","text":"秒,并且逻辑不涉及","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"共享资源读写操作","attrs":{}},{"type":"text","text":"(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"非临界区","attrs":{}},{"type":"text","text":"),另外还有两个函数","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incr","attrs":{}}],"attrs":{}},{"type":"text","text":"与","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incrTwo","attrs":{}}],"attrs":{}},{"type":"text","text":",都是在自增逻辑前执行了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"syncDbData","attrs":{}}],"attrs":{}},{"type":"text","text":"函数,只是使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"的姿势不同,一个是修饰在函数上,另一个是修饰在代码块上。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"public class SyncTest {\n\n private static int j = 0;\n\n\n /**\n * 同步库数据,比较耗时,代码资源不涉及共享资源读写操作。\n */\n public void syncDbData() {\n System.out.println(\"db数据开始同步------------\");\n try {\n //同步时间需要2秒\n Thread.sleep(2000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n System.out.println(\"db数据开始同步完成------------\");\n }\n\n //自增方法\n public synchronized void incr() {\n //start--临界区代码\n //同步库数据\n syncDbData();\n for (int i = 0; i < 10000; i++) {\n j++;\n }\n //end--临界区代码\n }\n\n //自增方法\n public void incrTwo() {\n //同步库数据\n syncDbData();\n synchronized (this) {\n //start--临界区代码\n for (int i = 0; i < 10000; i++) {\n j++;\n }\n //end--临界区代码\n }\n\n }\n\n public int getJ() {\n return j;\n }\n\n}\n\n\npublic class SyncMain {\n\n public static void main(String[] agrs) throws InterruptedException {\n //incr同步方法执行\n SyncTest syncTest = new SyncTest();\n Thread thread = new Thread(() -> syncTest.incr());\n Thread threadTwo = new Thread(() -> syncTest.incr());\n thread.start();\n threadTwo.start();\n thread.join();\n threadTwo.join();\n //最终打印结果是20000\n System.out.println(syncTest.getJ());\n\n //incrTwo同步块执行\n thread = new Thread(() -> syncTest.incrTwo());\n threadTwo = new Thread(() -> syncTest.incrTwo());\n thread.start();\n threadTwo.start();\n thread.join();\n threadTwo.join();\n //最终打印结果是40000\n System.out.println(syncTest.getJ());\n }\n\n}\n","attrs":{}}]},{"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":"先看看","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incr","attrs":{}}],"attrs":{}},{"type":"text","text":"同步方法执行,流程和前面没区别,只是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"锁定的范围太大,把","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"syncDbData()","attrs":{}}],"attrs":{}},{"type":"text","text":"也纳入","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"临界区","attrs":{}},{"type":"text","text":"中,多线程场景执行,会有性能上的浪费,因为","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"syncDbData()","attrs":{}}],"attrs":{}},{"type":"text","text":"完全可以让多线程","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"并行","attrs":{}},{"type":"text","text":"或","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"并发","attrs":{}},{"type":"text","text":"执行。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1f/1f2966d17d22c14d43b0efd7f00e2b6a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"text","text":"我们通过代码块的方式,来缩小范围,定义正确的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"临界区","attrs":{}},{"type":"text","text":",提升性能,目光转到","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incrTwo","attrs":{}}],"attrs":{}},{"type":"text","text":"同步块执行,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incrTwo","attrs":{}}],"attrs":{}},{"type":"text","text":"函数使用修饰代码块的方式同步,只对自增代码段进行锁定。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/66/6630aede8a91e0080861d0a5adde3550.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"text","text":"代码块同步方式除了灵活控制范围外,还能做线程间的协同工作,因为","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized ()","attrs":{}}],"attrs":{}},{"type":"text","text":"括号中能接收任何对象作为锁,所以可以通过","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Object","attrs":{}}],"attrs":{}},{"type":"text","text":"的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"wait、notify、notifyAll","attrs":{}}],"attrs":{}},{"type":"text","text":"等函数,做多线程间的通信协同(本文不对线程通信协同做展开,主角是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":",而且也不推荐去用这些方法,因为","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"LockSupport","attrs":{}}],"attrs":{}},{"type":"text","text":"工具类会是更好的选择)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"wait:当前线程暂停,释放锁","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"notify:释放锁,唤醒调用了wait的线程(如果有多个随机唤醒一个)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"notifyAll:释放锁,唤醒调用了wait的所有线程","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Synchronized原理","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":" public class SyncTest {\n\n private static int j = 0;\n\n\n /**\n * 同步库数据,比较耗时,代码资源不涉及共享资源读写操作。\n */\n public void syncDbData() {\n System.out.println(\"db数据开始同步------------\");\n try {\n //同步时间需要2秒\n Thread.sleep(2000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n System.out.println(\"db数据开始同步完成------------\");\n }\n\n //自增方法\n public synchronized void incr() {\n //start--临界区代码\n //同步库数据\n syncDbData();\n for (int i = 0; i < 10000; i++) {\n j++;\n }\n //end--临界区代码\n }\n\n //自增方法\n public void incrTwo() {\n //同步库数据\n syncDbData();\n synchronized (this) {\n //start--临界区代码\n for (int i = 0; i < 10000; i++) {\n j++;\n }\n //end--临界区代码\n }\n\n }\n\n public int getJ() {\n return j;\n }\n\n} \n","attrs":{}}]},{"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":"为了探究","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"原理,我们对上面的代码进行反编译,输出反编译后结果,看看底层是如何实现的(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"环境Java 11、win 10系统","attrs":{}},{"type":"text","text":")。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":" 只截取了incr与incrTwo函数内容\n \n public synchronized void incr();\n Code:\n 0: aload_0 \n 1: invokevirtual #11 // Method syncDbData:()V \n 4: iconst_0 \n 5: istore_1 \n 6: iload_1 \n 7: sipush 10000 \n 10: if_icmpge 27\n 13: getstatic #12 // Field j:I\n 16: iconst_1\n 17: iadd\n 18: putstatic #12 // Field j:I\n 21: iinc 1, 1\n 24: goto 6\n 27: return\n\n public void incrTwo(); \n Code:\n 0: aload_0\n 1: invokevirtual #11 // Method syncDbData:()V\n 4: aload_0\n 5: dup\n 6: astore_1\n 7: monitorenter //获取锁\n 8: iconst_0\n 9: istore_2\n 10: iload_2\n 11: sipush 10000\n 14: if_icmpge 31\n 17: getstatic #12 // Field j:I\n 20: iconst_1\n 21: iadd\n 22: putstatic #12 // Field j:I\n 25: iinc 2, 1\n 28: goto 10\n 31: aload_1\n 32: monitorexit //正常退出释放锁 \n 33: goto 41\n 36: astore_3\n 37: aload_1\n 38: monitorexit //异步退出释放锁 \n 39: aload_3\n 40: athrow\n 41: return\n","attrs":{}}]},{"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","marks":[{"type":"strong","attrs":{}}],"text":"ps:对上面指令感兴趣的读者,可以百度或google一下“JVM 虚拟机字节码指令表”","attrs":{}}]},{"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":"先看","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incrTwo","attrs":{}}],"attrs":{}},{"type":"text","text":"函数,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incrTwo","attrs":{}}],"attrs":{}},{"type":"text","text":"是代码块方式同步,在反编译后的结果中,我们发现存在","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitorenter","attrs":{}}],"attrs":{}},{"type":"text","text":"与","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitorexit","attrs":{}}],"attrs":{}},{"type":"text","text":"指令(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"获取锁、释放锁","attrs":{}},{"type":"text","text":")。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"monitorenter","attrs":{}}],"attrs":{}},{"type":"text","text":"指令插入到同步代码块的开始位置,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitorexit","attrs":{}}],"attrs":{}},{"type":"text","text":"指令插入到同步代码块的结束位置,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"J V M","attrs":{}}],"attrs":{}},{"type":"text","text":"需要保证每一个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitorenter","attrs":{}}],"attrs":{}},{"type":"text","text":"都有","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitorexit","attrs":{}}],"attrs":{}},{"type":"text","text":"与之对应。","attrs":{}}]},{"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","marks":[{"type":"strong","attrs":{}}],"text":"任何对象","attrs":{}},{"type":"text","text":"都有一个监视器锁(","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","text":")关联,线程执行","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitorenter","attrs":{}}],"attrs":{}},{"type":"text","text":"指令时尝试获取","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","text":"的所有权。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"如果","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"的进入数为","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"0","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",则该线程进入","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",然后将进入数设置为","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",该线程为","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"的所有者","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"如果线程已经占有该","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",重新进入,则","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"的进入数加","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"线程执行","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitorexit","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"的进入数-1,执行过多少次","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitorenter","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",最终要执行对应次数的","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitorexit","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"如果其他线程已经占用","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",则该线程进入阻塞状态,直到","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"的进入数为0,再重新尝试获取","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"的所有权","attrs":{}}]}]}],"attrs":{}},{"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":"回过头看","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incr","attrs":{}}],"attrs":{}},{"type":"text","text":"函数,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incr","attrs":{}}],"attrs":{}},{"type":"text","text":"是普通函数方式同步,虽然在反编译后的结果中没有看到","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitorenter","attrs":{}}],"attrs":{}},{"type":"text","text":"与","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitorexit","attrs":{}}],"attrs":{}},{"type":"text","text":"指令,但是实际执行的流程与","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incrTwo","attrs":{}}],"attrs":{}},{"type":"text","text":"函数一样,通过","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"monitor","attrs":{}}],"attrs":{}},{"type":"text","text":"来执行,只不过它是一种隐式的方式来实现,最后放一张流程图。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/fc/fc66b23cb89ca940c6ad9101cf5548d3.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Synchronized优化","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Jdk 1.5","attrs":{}}],"attrs":{}},{"type":"text","text":"以后对","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"关键字做了各种的优化,经过优化后","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"已经变得越来越快了,这也是为什么官方建议使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"的原因,具体的优化点如下。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"锁粗化","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"锁消除","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"锁升级","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"锁粗化","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"互斥的临界区","attrs":{}},{"type":"text","text":"范围应该尽可能小,这样做的目的是为了使同步的操作数量尽可能缩小,缩短阻塞时间,如果存在锁竞争,那么等待锁的线程也能尽快拿到锁。","attrs":{}}]},{"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":"但是加锁解锁也需要消耗资源,如果存在一系列的连续加锁解锁操作,可能会导致不必要的性能损耗,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"锁粗化","attrs":{}},{"type":"text","text":"就是将「","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"多个连续的加锁、解锁操作连接在一起","attrs":{}},{"type":"text","text":"」,扩展成一个范围更大的锁,避免频繁的加锁解锁操作。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e4/e4b668bc41040139f7a7e091c08a2960.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"codeinline","content":[{"type":"text","text":"J V M","attrs":{}}],"attrs":{}},{"type":"text","text":"会检测到一连串的操作都对同一个对象加锁(","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"for","attrs":{}}],"attrs":{}},{"type":"text","text":"循环","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"10000","attrs":{}}],"attrs":{}},{"type":"text","text":"次执行","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"j++","attrs":{}}],"attrs":{}},{"type":"text","text":",没有锁粗化就要进行","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"10000","attrs":{}}],"attrs":{}},{"type":"text","text":"次加锁/解锁),此时","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"J V M","attrs":{}}],"attrs":{}},{"type":"text","text":"就会将加锁的范围粗化到这一连串操作的外部(比如","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"for","attrs":{}}],"attrs":{}},{"type":"text","text":"循环体外),使得这一连串操作只需要加一次锁即可。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"锁消除","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Java","attrs":{}}],"attrs":{}},{"type":"text","text":"虚拟机在","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"JIT","attrs":{}}],"attrs":{}},{"type":"text","text":"编译时(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"可以简单理解为当某段代码即将第一次被执行时进行编译,又称即时编译","attrs":{}},{"type":"text","text":"),通过对运行上下文的扫描,经过逃逸分析(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"对象在函数中被使用,也可能被外部函数所引用,称为函数逃逸","attrs":{}},{"type":"text","text":"),去除不可能存在共享资源竞争的锁,通过这种方式消除没有必要的锁,可以节省毫无意义的时间消耗。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/09/094680238f44c254f269f98c16d7c07b.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"text","text":"代码中使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Object","attrs":{}}],"attrs":{}},{"type":"text","text":"作为锁,但是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Object","attrs":{}}],"attrs":{}},{"type":"text","text":"对象的生命周期只在","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incrFour()","attrs":{}}],"attrs":{}},{"type":"text","text":"函数中,并不会被其他线程所访问到,所以在","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"J I T","attrs":{}}],"attrs":{}},{"type":"text","text":"编译阶段就会被优化掉(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"此处的","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Object","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"属于没有逃逸的对象","attrs":{}},{"type":"text","text":")。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"锁升级","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Java","attrs":{}}],"attrs":{}},{"type":"text","text":"中每个对象都拥有对象头,对象头由","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Mark World","attrs":{}}],"attrs":{}},{"type":"text","text":" 、指向类的指针、以及数组长度三部分组成,本文,我们只需要关心","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Mark World","attrs":{}}],"attrs":{}},{"type":"text","text":" 即可,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" Mark World","attrs":{}}],"attrs":{}},{"type":"text","text":" 记录了对象的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"HashCode","attrs":{}}],"attrs":{}},{"type":"text","text":"、分代年龄和锁标志位信息。","attrs":{}}]},{"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","marks":[{"type":"strong","attrs":{}}],"text":"Mark World简化结构","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/06/0647016ffe03270e54a877126d3cb325.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"text","text":"读者们只需知道,锁的升级变化,体现在锁对象的对象头","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Mark World","attrs":{}}],"attrs":{}},{"type":"text","text":"部分,也就是说","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Mark World","attrs":{}}],"attrs":{}},{"type":"text","text":"的内容会随着锁升级而改变。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Java1.5","attrs":{}}],"attrs":{}},{"type":"text","text":"以后为了减少获取锁和释放锁带来的性能消耗,引入了","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"偏向锁","attrs":{}},{"type":"text","text":"和","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"轻量级锁","attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"的升级顺序是 「","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"无锁-->偏向锁-->轻量级锁-->重量级锁,只会升级不会降级","attrs":{}},{"type":"text","text":"」","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"偏向锁","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在大多数情况下,锁总是由同一线程多次获得,不存在多线程竞争,所以出现了偏向锁,其目标就是在只有一个线程执行同步代码块时,降低获取锁带来的消耗,提高性能(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"可以通过J V M参数关闭偏向锁:-XX:-UseBiasedLocking=false,关闭之后程序默认会进入轻量级锁状态","attrs":{}},{"type":"text","text":")。","attrs":{}}]},{"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":"线程执行同步代码或方法前,线程只需要判断对象头的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Mark Word","attrs":{}}],"attrs":{}},{"type":"text","text":"中线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ID","attrs":{}}],"attrs":{}},{"type":"text","text":"与当前线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ID","attrs":{}}],"attrs":{}},{"type":"text","text":"是否一致,如果一致直接执行同步代码或方法,具体流程如下","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4a/4a10a6e21c484fb3be21fcd3b8e109e0.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"无锁状态,存储内容「是否为偏向锁(","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"0","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":")」,锁标识位","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"01","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"CAS","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"设置当前线程ID到","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Mark Word","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"存储内容中","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"是否为偏向锁","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"0","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" => 是否为偏向锁","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"执行同步代码或方法","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"偏向锁状态,存储内容「是否为偏向锁(","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":")、线程ID」,锁标识位","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"01","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"对比线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ID","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"是否一致,如果一致执行同步代码或方法,否则进入下面的流程","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"如果不一致,","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"CAS","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"将","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Mark Word","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"的线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ID","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"设置为当前线程","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ID","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",设置成功,执行同步代码或方法,否则进入下面的流程","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"CAS","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"设置失败,证明存在多线程竞争情况,触发撤销偏向锁,当到达全局安全点,偏向锁的线程被挂起,偏向锁升级为轻量级锁,然后在安全点的位置恢复继续往下执行。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"轻量级锁","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"轻量级锁考虑的是竞争锁对象的线程不多,持有锁时间也不长的场景。因为阻塞线程需要","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"C P U","attrs":{}}],"attrs":{}},{"type":"text","text":"从用户态转到内核态,代价较大,如果刚刚阻塞不久这个锁就被释放了,那这个代价就有点得不偿失,所以干脆不阻塞这个线程,让它自旋一段时间等待锁释放。","attrs":{}}]},{"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":"当前线程持有的锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。轻量级锁的获取主要有两种情况:① 当关闭偏向锁功能时;② 多个线程竞争偏向锁导致偏向锁升级为轻量级锁。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4a/4a70ca6d41ed62e92e2a0fff1c11100e.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"无锁状态,存储内容「是否为偏向锁(","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"0","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":")」,锁标识位","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"01","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"关闭偏向锁功能时","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"CAS","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"设置当前线程栈中锁记录的指针到","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Mark Word","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"存储内容","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"锁标识位设置为","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"00","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"执行同步代码或方法","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"释放锁时,还原来","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Mark Word","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"内容","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"轻量级锁状态,存储内容「线程栈中锁记录的指针」,锁标识位","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"00","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"(存储内容的线程是指\"持有轻量级锁的线程\")","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"CAS","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"设置当前线程栈中锁记录的指针到","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Mark Word","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"存储内容,设置成功获取轻量级锁,执行同步块代码或方法,否则执行下面的逻辑","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"设置失败,证明多线程存在一定竞争,线程自旋上一步的操作,自旋一定次数后还是失败,轻量级锁升级为重量级锁","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Mark Word","attrs":{}}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"存储内容替换成重量级锁指针,锁标记位","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"10","attrs":{}}],"attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"重量级锁","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"轻量级锁膨胀之后,就升级为重量级锁,重量级锁是依赖操作系统的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"MutexLock","attrs":{}}],"attrs":{}},{"type":"text","text":"(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"互斥锁","attrs":{}},{"type":"text","text":")来实现的,需要从用户态转到内核态,这个成本非常高,这就是为什么","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Java1.6","attrs":{}}],"attrs":{}},{"type":"text","text":"之前","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Synchronized","attrs":{}}],"attrs":{}},{"type":"text","text":"效率低的原因。","attrs":{}}]},{"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":"升级为重量级锁时,锁标志位的状态值变为","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"10","attrs":{}}],"attrs":{}},{"type":"text","text":",此时","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Mark Word","attrs":{}}],"attrs":{}},{"type":"text","text":"中存储内容的是重量级锁的指针,等待锁的线程都会进入阻塞状态,下面是简化版的锁升级过程。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4f/4f39fcc93208dc073796009af7b1b8b8.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"历史好文推荐","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/GR7lLGp9JH4bsAgQB3uLrw","title":"","type":null},"content":[{"type":"text","text":"由浅入深CAS,小白也能与BAT面试官对线","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/48OLw2koXwrcJ5YOKSNmFw","title":"","type":null},"content":[{"type":"text","text":"小白也能看懂的Java内存模型","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/woFmXOt5zOxidlkduIfruA","title":"","type":null},"content":[{"type":"text","text":"保姆级教学,22张图揭开ThreadLocal","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/jhOSjVyRA6rNKqVT2pKMIQ","title":"","type":null},"content":[{"type":"text","text":"进程、线程与协程傻傻分不清?一文带你吃透!","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/_ATueOBN4UM2bim_1hDBFQ","title":"","type":null},"content":[{"type":"text","text":"什么是线程安全?一文带你深入理解","attrs":{}}]}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"关于我","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里是阿星,一个热爱技术的Java程序猿,公众号 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「程序猿阿星」","attrs":{}},{"type":"text","text":"里将会定期分享操作系统、计算机网络、Java、分布式、数据库等精品原创文章,2021,与您在 Be Better 的路上共同成长!。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/22/2205b202fa895835f7d7d99379308e9f.gif","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"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},"content":[{"type":"text","text":"非常感谢各位小哥哥小姐姐们能看到这里,原创不易,文章有帮助可以关注、点个赞、分享与评论,都是支持(莫要白嫖)!","attrs":{}}]},{"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":"愿你我都能奔赴在各自想去的路上,我们下篇文章见","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/cd/cd93a342bb6bb4cd5478beb9f35689e0.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章