1. Why use synchronized
The reason for using synchronized
is that : it can ensure that multiple threads can only have one at the same time, The thread is in a method or synchronization block,It guarantees the visibility and exclusivity of the thread’s access to variables.
Second, the principle of synchronized
Before JDK 1.6
,synchronized
is implemented based on object monitoring , This is also known as a weight lock. By default ,Each object has an associated Monitor
, and each Monitor
contains an EntryCount
counter ,It is the key for synchronized
to achieve reentrancy.
After JDK 1.6
, a series of optimization measures for locks , by introducing spin locks, adaptive spin locks, lock elimination, Lock coarsening, biased locks, lightweight locks and other technologies to reduce the overhead of lock operations.
The ultimate goal of these optimization measures is to reduce the overhead of lock operations ,However, what it changes is only the way the lock is implemented,But the basic principle of locking and unlocking has not changed . This article mainly introduces the use of synchronized
,so,in the following introduction,we still analyze it in the way of weight lock which is easier to understand, ;In a later article,let’s talk about the optimized implementation strategy again.
2.1 Entering a synchronization method or code block
When a thread executes a synchronization method or code block of an object , Whether the associated Monitor's EntryCount
is 0
:
- If
EntryCount
is0
,then the thread will setMonitor's EntryCount
to1
, and become theMonitor
Owner,Then execute the statement in the method or code block. - If
EntryCount
is not0
, then it will check the holding of theMonitor
associated with the object Which thread it is : - The first case : the thread holding the
Monitor
is currently trying to get theMonitor
The thread of ,then add1
to the value ofEntryCount
, to continue executing the statement in the method or code block. - The second case : holds the
Monitor
is another thread , then the thread enters the blocking state, untilEntryCount
becomes0
.
2.2 Exiting a synchronous method or code block
When a thread exits from a synchronous method or code block, will EntryCount
minus 1
, If EntryCount
becomes 0
, then the thread will release what it holds The Monitor
. Previously those threads blocked in synchronized
will try to acquire Monitor
, threads that successfully acquire Monitor
can enter the synchronization method or code block.
Third, synchronized use
For the use of synchronized
, we have two classification methods:
- Classify according to usage scenarios
- Classify according to the objects associated with
Monitor
.
3.1 Classification according to usage scenarios
Many articles introducing synchronized
, are based on usage scenarios Classified,Generally speaking, it can be divided into the following four usage scenarios,And in each scenario, according to the different objects associated with Monitor
, will derive another Usage :
- Static method
//Static method , uses Class Class lock synchronized public static void staticMethod() {}
- Static method code block
private static final byte[] mStaticLockByte = new byte[1];//Static method code block 1, uses Class class lock public static void staticBlock1() {synchronized (SynchronizedObject.class) {}}//Static method code block 2, uses internal static variable lock public static void staticBlock2() {synchronized (mStaticLockByte) {} }
- Common method
//Common method , uses The object lock that calls this method synchronized public void method() {}
- Common method code block
private static final byte[] mStaticLockByte = new byte[1];private final bytee[] mLockByte = new byte[1];//Ordinary method code block 1, uses Class class lock public void block1() {synchronized (SynchronizedObject.class) {}}//Common method code block 2, uses the variable lock of mLockByte public void block2() {synchronized (mLockByte) {} //Variables need to be declared final}//Common method code block 3,used It is the variable lock of mStaticLockByte public void block3() {synchronized (mStaticLockByte) {} }//Common method Code block 4, uses the object lock that calls this method public void block4() {synchronized (this) {}}
3.2 According to the object classification associated with Monitor
Categorized according to usage scenarios ,mainly to let everyone know how to use the synchronized
keyword ,however, to really understand synchronized
& #xff0c;You need to combine the synchronized
principle mentioned in the second section ,In fact, the various scenarios mentioned in 3.1
, are all related to Monitor
is related to , then from the object associated with Monitor
, we will redefine 8
in 3.1
code>Scene reclassification :
Class
object :- Static method
- Static method code block 1 –
SynchronizedObject.class
- Ordinary method code block 1 –
SynchronizedObject.class
- The object calling the method
- Common method
- Common method code block 4 –
this
- Static object
- Static method code block 2 –
mStaticLockByte
- Common method code block 3 –
mStaticLockByte
- Non-static object
- Common method Code block 1 –
mLockByte
If the usage scenario belongs to the same category above, then it is possible to cause thread blocking in synchronized keyword , give an example , if
A
thread accesses (class one) through a static method and does not exit from that method) xff1a;
- At this time, the
B
thread accesses (category 2), through an ordinary method of an object, then it will not Blocked,This is because theMonitor
associated with the object calling this method is not held. - If the
B
thread uses a static method code block to access , and the static method code block usesSynchronizedObject.class
to Modification (Classification 1),Since these two usage scenarios belong to the same category,then theB
thread will enter the blocked state, ;This is because theMonitor
associated with theSynchronizedObject
class has been held by theA
thread.
4. Summary
On the surface, the use of ,synchronized
can be simply divided into synchronization methods and synchronization codes Block , But under what circumstances will cause a thread to block on synchronized
, You need to analyze the Monitor that the
is already held by other threads. synchronized
method tries to get