synchronized 三种用法

    1. synchronize static method ,synchronized 修饰静态方法
    2. synchronize instance method , synchronized 修饰实例方法
    3. synchronize{ //todo } , synchronized 修饰代码块

    相对三种方式的实现方式分析:
    java 代码:

    1. public class SyncKeyWord {
    2. public SyncKeyWord() {
    3. }
    4. public static synchronized void staticMethod() {
    5. }
    6. public synchronized void instanceMethod() {
    7. }
    8. public void codeBlock() {
    9. String var1 = "obj";
    10. synchronized("obj") {
    11. ;
    12. }
    13. }
    14. }

    字节码文件:

    1. public class keyword.SyncKeyWord
    2. minor version: 0
    3. major version: 52
    4. flags: ACC_PUBLIC, ACC_SUPER
    5. Constant pool:
    6. #1 = Methodref #4.#21 // java/lang/Object."<init>":()V
    7. #2 = String #22 // obj
    8. #3 = Class #23 // keyword/SyncKeyWord
    9. #4 = Class #24 // java/lang/Object
    10. #5 = Utf8 <init>
    11. #6 = Utf8 ()V
    12. #7 = Utf8 Code
    13. #8 = Utf8 LineNumberTable
    14. #9 = Utf8 LocalVariableTable
    15. #10 = Utf8 this
    16. #11 = Utf8 Lkeyword/SyncKeyWord;
    17. #12 = Utf8 staticMethod
    18. #13 = Utf8 instanceMethod
    19. #14 = Utf8 codeBlock
    20. #15 = Utf8 StackMapTable
    21. #16 = Class #23 // keyword/SyncKeyWord
    22. #17 = Class #24 // java/lang/Object
    23. #18 = Class #25 // java/lang/Throwable
    24. #19 = Utf8 SourceFile
    25. #20 = Utf8 SyncKeyWord.java
    26. #21 = NameAndType #5:#6 // "<init>":()V
    27. #22 = Utf8 obj
    28. #23 = Utf8 keyword/SyncKeyWord
    29. #24 = Utf8 java/lang/Object
    30. #25 = Utf8 java/lang/Throwable
    31. {
    32. public keyword.SyncKeyWord();
    33. descriptor: ()V
    34. flags: ACC_PUBLIC
    35. Code:
    36. stack=1, locals=1, args_size=1
    37. 0: aload_0
    38. 1: invokespecial #1 // Method java/lang/Object."<init>":()V
    39. 4: return
    40. LineNumberTable:
    41. line 9: 0
    42. LocalVariableTable:
    43. Start Length Slot Name Signature
    44. 0 5 0 this Lkeyword/SyncKeyWord;
    45. public static synchronized void staticMethod();
    46. descriptor: ()V
    47. flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED ## 此处标记 静态/同步
    48. Code:
    49. stack=0, locals=0, args_size=0
    50. 0: return
    51. LineNumberTable:
    52. line 13: 0
    53. public synchronized void instanceMethod();
    54. descriptor: ()V
    55. flags: ACC_PUBLIC, ACC_SYNCHRONIZED ## 此处标记 同步
    56. Code:
    57. stack=0, locals=1, args_size=1
    58. 0: return
    59. LineNumberTable:
    60. line 17: 0
    61. LocalVariableTable:
    62. Start Length Slot Name Signature
    63. 0 1 0 this Lkeyword/SyncKeyWord;
    64. public void codeBlock();
    65. descriptor: ()V
    66. flags: ACC_PUBLIC
    67. Code:
    68. stack=2, locals=3, args_size=1
    69. 0: ldc #2 // String obj
    70. 2: dup
    71. 3: astore_1
    72. 4: monitorenter ## 此处开启 monitor
    73. 5: aload_1
    74. 6: monitorexit ## 退出 monitor 释放锁
    75. 7: goto 15
    76. 10: astore_2
    77. 11: aload_1
    78. 12: monitorexit ## 代码异常时 需要退出 monitor 释放锁
    79. 13: aload_2
    80. 14: athrow
    81. 15: return
    82. Exception table:
    83. from to target type
    84. 5 7 10 any
    85. 10 13 10 any
    86. LineNumberTable:
    87. line 20: 0
    88. line 22: 5
    89. line 23: 15
    90. LocalVariableTable:
    91. Start Length Slot Name Signature
    92. 0 16 0 this Lkeyword/SyncKeyWord;
    93. StackMapTable: number_of_entries = 2
    94. frame_type = 255 /* full_frame */
    95. offset_delta = 10
    96. locals = [ class keyword/SyncKeyWord, class java/lang/Object ]
    97. stack = [ class java/lang/Throwable ]
    98. frame_type = 250 /* chop */
    99. offset_delta = 4
    100. }

    对于代码块, Jvm 开启了一个monitor,这个monitor 控制了对象 obj 的对象锁,其他线程要进入,只能等 monitor释放obj的对象锁
    对于 实例方法,对方法进行了 同步标记 ,然后通过获取实例对象的对象锁进行控制
    对于静态方法,对方法做了 静态同步标记,通过 锁定 Class对象 的对象锁 进行控制
    对应synchronized ,其所有的控制都是基于Java 对象 头的 markwork锁标识来操作的。

    对象头的组成部分: Markword 类指针 数组长度(数组对象才有)

    • markword
      • 32位JVM中markword | 锁状态 | 25bit | | 4bit | 1bit | 2bit | | —- | —- | —- | —- | —- | —- | | | 23bit | 2bit | | 是否偏向锁 | | | 无锁 | 对象Hashcode | | 分代年龄 | 0 | | | 偏向锁 | 线程ID | Epoch | | | | | 轻量级锁 | | | | | | | 重量级锁 | | | | | | | GC标记 | | | | | |

    monitor 是由 ObjectMonitor 实现的,

    1. ObjectMonitor() {
    2. _header = NULL;
    3. _count = 0; ## 等待的线程数
    4. _waiters = 0,
    5. _recursions = 0;
    6. _object = NULL;
    7. _owner = NULL; ## 持有锁的线程
    8. _WaitSet = NULL; ##处于wait的线程,加入到这个set
    9. _WaitSetLock = 0 ;
    10. _Responsible = NULL ;
    11. _succ = NULL ;
    12. _cxq = NULL ;
    13. FreeNext = NULL ;
    14. _EntryList = NULL ; ## 处于等待锁block的线程,加入到这里
    15. _SpinFreq = 0 ;
    16. _SpinClock = 0 ;
    17. OwnerIsThread = 0 ;
    18. _previous_owner_tid = 0;
    19. }

    ObjectMonitor 源码

    1. /*
    2. * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
    3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4. *
    5. * This code is free software; you can redistribute it and/or modify it
    6. * under the terms of the GNU General Public License version 2 only, as
    7. * published by the Free Software Foundation.
    8. *
    9. * This code is distributed in the hope that it will be useful, but WITHOUT
    10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
    12. * version 2 for more details (a copy is included in the LICENSE file that
    13. * accompanied this code).
    14. *
    15. * You should have received a copy of the GNU General Public License version
    16. * 2 along with this work; if not, write to the Free Software Foundation,
    17. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18. *
    19. * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20. * or visit www.oracle.com if you need additional information or have any
    21. * questions.
    22. *
    23. */
    24. #ifndef SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
    25. #define SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
    26. #include "runtime/os.hpp"
    27. #include "runtime/park.hpp"
    28. #include "runtime/perfData.hpp"
    29. // ObjectWaiter serves as a "proxy" or surrogate thread.
    30. // TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
    31. // ParkEvent instead. Beware, however, that the JVMTI code
    32. // knows about ObjectWaiters, so we'll have to reconcile that code.
    33. // See next_waiter(), first_waiter(), etc.
    34. class ObjectWaiter : public StackObj {
    35. public:
    36. enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ;
    37. enum Sorted { PREPEND, APPEND, SORTED } ;
    38. ObjectWaiter * volatile _next;
    39. ObjectWaiter * volatile _prev;
    40. Thread* _thread;
    41. jlong _notifier_tid;
    42. ParkEvent * _event;
    43. volatile int _notified ;
    44. volatile TStates TState ;
    45. Sorted _Sorted ; // List placement disposition
    46. bool _active ; // Contention monitoring is enabled
    47. public:
    48. ObjectWaiter(Thread* thread);
    49. void wait_reenter_begin(ObjectMonitor *mon);
    50. void wait_reenter_end(ObjectMonitor *mon);
    51. };
    52. // WARNING:
    53. // This is a very sensitive and fragile class. DO NOT make any
    54. // change unless you are fully aware of the underlying semantics.
    55. // This class can not inherit from any other class, because I have
    56. // to let the displaced header be the very first word. Otherwise I
    57. // have to let markOop include this file, which would export the
    58. // monitor data structure to everywhere.
    59. //
    60. // The ObjectMonitor class is used to implement JavaMonitors which have
    61. // transformed from the lightweight structure of the thread stack to a
    62. // heavy weight lock due to contention
    63. // It is also used as RawMonitor by the JVMTI
    64. class ObjectMonitor {
    65. public:
    66. enum {
    67. OM_OK, // no error
    68. OM_SYSTEM_ERROR, // operating system error
    69. OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
    70. OM_INTERRUPTED, // Thread.interrupt()
    71. OM_TIMED_OUT // Object.wait() timed out
    72. };
    73. public:
    74. // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
    75. // ByteSize would also be an appropriate type.
    76. static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); }
    77. static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); }
    78. static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); }
    79. static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); }
    80. static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); }
    81. static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq) ; }
    82. static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ) ; }
    83. static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); }
    84. static int FreeNext_offset_in_bytes() { return offset_of(ObjectMonitor, FreeNext); }
    85. static int WaitSet_offset_in_bytes() { return offset_of(ObjectMonitor, _WaitSet) ; }
    86. static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);}
    87. static int Spinner_offset_in_bytes() { return offset_of(ObjectMonitor, _Spinner); }
    88. public:
    89. // Eventaully we'll make provisions for multiple callbacks, but
    90. // now one will suffice.
    91. static int (*SpinCallbackFunction)(intptr_t, int) ;
    92. static intptr_t SpinCallbackArgument ;
    93. public:
    94. markOop header() const;
    95. void set_header(markOop hdr);
    96. intptr_t is_busy() const {
    97. // TODO-FIXME: merge _count and _waiters.
    98. // TODO-FIXME: assert _owner == null implies _recursions = 0
    99. // TODO-FIXME: assert _WaitSet != null implies _count > 0
    100. return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ;
    101. }
    102. intptr_t is_entered(Thread* current) const;
    103. void* owner() const;
    104. void set_owner(void* owner);
    105. intptr_t waiters() const;
    106. intptr_t count() const;
    107. void set_count(intptr_t count);
    108. intptr_t contentions() const ;
    109. intptr_t recursions() const { return _recursions; }
    110. // JVM/DI GetMonitorInfo() needs this
    111. ObjectWaiter* first_waiter() { return _WaitSet; }
    112. ObjectWaiter* next_waiter(ObjectWaiter* o) { return o->_next; }
    113. Thread* thread_of_waiter(ObjectWaiter* o) { return o->_thread; }
    114. // initialize the monitor, exception the semaphore, all other fields
    115. // are simple integers or pointers
    116. ObjectMonitor() {
    117. _header = NULL;
    118. _count = 0;
    119. _waiters = 0,
    120. _recursions = 0;
    121. _object = NULL;
    122. _owner = NULL;
    123. _WaitSet = NULL;
    124. _WaitSetLock = 0 ;
    125. _Responsible = NULL ;
    126. _succ = NULL ;
    127. _cxq = NULL ;
    128. FreeNext = NULL ;
    129. _EntryList = NULL ;
    130. _SpinFreq = 0 ;
    131. _SpinClock = 0 ;
    132. OwnerIsThread = 0 ;
    133. _previous_owner_tid = 0;
    134. }
    135. ~ObjectMonitor() {
    136. // TODO: Add asserts ...
    137. // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
    138. // _count == 0 _EntryList == NULL etc
    139. }
    140. private:
    141. void Recycle () {
    142. // TODO: add stronger asserts ...
    143. // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
    144. // _count == 0 EntryList == NULL
    145. // _recursions == 0 _WaitSet == NULL
    146. // TODO: assert (is_busy()|_recursions) == 0
    147. _succ = NULL ;
    148. _EntryList = NULL ;
    149. _cxq = NULL ;
    150. _WaitSet = NULL ;
    151. _recursions = 0 ;
    152. _SpinFreq = 0 ;
    153. _SpinClock = 0 ;
    154. OwnerIsThread = 0 ;
    155. }
    156. public:
    157. void* object() const;
    158. void* object_addr();
    159. void set_object(void* obj);
    160. bool check(TRAPS); // true if the thread owns the monitor.
    161. void check_slow(TRAPS);
    162. void clear();
    163. static void sanity_checks(); // public for -XX:+ExecuteInternalVMTests
    164. // in PRODUCT for -XX:SyncKnobs=Verbose=1
    165. #ifndef PRODUCT
    166. void verify();
    167. void print();
    168. #endif
    169. bool try_enter (TRAPS) ;
    170. void enter(TRAPS);
    171. void exit(bool not_suspended, TRAPS);
    172. void wait(jlong millis, bool interruptable, TRAPS);
    173. void notify(TRAPS);
    174. void notifyAll(TRAPS);
    175. // Use the following at your own risk
    176. intptr_t complete_exit(TRAPS);
    177. void reenter(intptr_t recursions, TRAPS);
    178. private:
    179. void AddWaiter (ObjectWaiter * waiter) ;
    180. static void DeferredInitialize();
    181. ObjectWaiter * DequeueWaiter () ;
    182. void DequeueSpecificWaiter (ObjectWaiter * waiter) ;
    183. void EnterI (TRAPS) ;
    184. void ReenterI (Thread * Self, ObjectWaiter * SelfNode) ;
    185. void UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ;
    186. int TryLock (Thread * Self) ;
    187. int NotRunnable (Thread * Self, Thread * Owner) ;
    188. int TrySpin_Fixed (Thread * Self) ;
    189. int TrySpin_VaryFrequency (Thread * Self) ;
    190. int TrySpin_VaryDuration (Thread * Self) ;
    191. void ctAsserts () ;
    192. void ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ;
    193. bool ExitSuspendEquivalent (JavaThread * Self) ;
    194. private:
    195. friend class ObjectSynchronizer;
    196. friend class ObjectWaiter;
    197. friend class VMStructs;
    198. // WARNING: this must be the very first word of ObjectMonitor
    199. // This means this class can't use any virtual member functions.
    200. volatile markOop _header; // displaced object header word - mark
    201. void* volatile _object; // backward object pointer - strong root
    202. double SharingPad [1] ; // temp to reduce false sharing
    203. // All the following fields must be machine word aligned
    204. // The VM assumes write ordering wrt these fields, which can be
    205. // read from other threads.
    206. protected: // protected for jvmtiRawMonitor
    207. void * volatile _owner; // pointer to owning thread OR BasicLock
    208. volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
    209. volatile intptr_t _recursions; // recursion count, 0 for first entry
    210. private:
    211. int OwnerIsThread ; // _owner is (Thread *) vs SP/BasicLock
    212. ObjectWaiter * volatile _cxq ; // LL of recently-arrived threads blocked on entry.
    213. // The list is actually composed of WaitNodes, acting
    214. // as proxies for Threads.
    215. protected:
    216. ObjectWaiter * volatile _EntryList ; // Threads blocked on entry or reentry.
    217. private:
    218. Thread * volatile _succ ; // Heir presumptive thread - used for futile wakeup throttling
    219. Thread * volatile _Responsible ;
    220. int _PromptDrain ; // rqst to drain cxq into EntryList ASAP
    221. volatile int _Spinner ; // for exit->spinner handoff optimization
    222. volatile int _SpinFreq ; // Spin 1-out-of-N attempts: success rate
    223. volatile int _SpinClock ;
    224. volatile int _SpinDuration ;
    225. volatile intptr_t _SpinState ; // MCS/CLH list of spinners
    226. // TODO-FIXME: _count, _waiters and _recursions should be of
    227. // type int, or int32_t but not intptr_t. There's no reason
    228. // to use 64-bit fields for these variables on a 64-bit JVM.
    229. volatile intptr_t _count; // reference count to prevent reclaimation/deflation
    230. // at stop-the-world time. See deflate_idle_monitors().
    231. // _count is approximately |_WaitSet| + |_EntryList|
    232. protected:
    233. volatile intptr_t _waiters; // number of waiting threads
    234. private:
    235. protected:
    236. ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
    237. private:
    238. volatile int _WaitSetLock; // protects Wait Queue - simple spinlock
    239. public:
    240. int _QMix ; // Mixed prepend queue discipline
    241. ObjectMonitor * FreeNext ; // Free list linkage
    242. intptr_t StatA, StatsB ;
    243. public:
    244. static void Initialize () ;
    245. static PerfCounter * _sync_ContendedLockAttempts ;
    246. static PerfCounter * _sync_FutileWakeups ;
    247. static PerfCounter * _sync_Parks ;
    248. static PerfCounter * _sync_EmptyNotifications ;
    249. static PerfCounter * _sync_Notifications ;
    250. static PerfCounter * _sync_SlowEnter ;
    251. static PerfCounter * _sync_SlowExit ;
    252. static PerfCounter * _sync_SlowNotify ;
    253. static PerfCounter * _sync_SlowNotifyAll ;
    254. static PerfCounter * _sync_FailedSpins ;
    255. static PerfCounter * _sync_SuccessfulSpins ;
    256. static PerfCounter * _sync_PrivateA ;
    257. static PerfCounter * _sync_PrivateB ;
    258. static PerfCounter * _sync_MonInCirculation ;
    259. static PerfCounter * _sync_MonScavenged ;
    260. static PerfCounter * _sync_Inflations ;
    261. static PerfCounter * _sync_Deflations ;
    262. static PerfLongVariable * _sync_MonExtant ;
    263. public:
    264. static int Knob_Verbose;
    265. static int Knob_SpinLimit;
    266. void* operator new (size_t size) throw() {
    267. return AllocateHeap(size, mtInternal);
    268. }
    269. void* operator new[] (size_t size) throw() {
    270. return operator new (size);
    271. }
    272. void operator delete(void* p) {
    273. FreeHeap(p, mtInternal);
    274. }
    275. void operator delete[] (void *p) {
    276. operator delete(p);
    277. }
    278. };
    279. #undef TEVENT
    280. #define TEVENT(nom) {if (SyncVerbose) FEVENT(nom); }
    281. #define FEVENT(nom) { static volatile int ctr = 0 ; int v = ++ctr ; if ((v & (v-1)) == 0) { ::printf (#nom " : %d \n", v); ::fflush(stdout); }}
    282. #undef TEVENT
    283. #define TEVENT(nom) {;}
    284. #endif // SHARE_VM_RUNTIME_OBJECTMONITOR_HPP