Story characters.
Lao Wang - JVM
Xiao Nan - Thread.
Little Girl - Thread.
Room - Object.
On the door of the room - anti-theft lock - monitor-heavyweight lock.
Room on the door - Xiao Nan schoolbag - lightweight lock.
On the door of the room - engraved with the name of Konan - Biased lock - The object is exclusive to a thread.
Batch re-inscribed - A class of biased locks revoke reaches the 20 threshold - Bulk re-biased.
Can't engrave names - Revoke bias locks on objects of this class in batches, and set the class to be unbiased.
Xiao Nan wanted to use the room to ensure that the calculations were not interfered with by other people (atomicity), and initially, he used an anti-theft lock to lock the door when the context was switched. In this way, even if he leaves, no one else can enter the door, and his job is safe.
However, in many cases, no one competes with him for the right to use the room. The little girl wants to use the room, but the time of use is staggered, Xiao Nan uses it during the day, and the little girl uses it at night. It's too much trouble to lock it every time, is there an easier way?
Xiao Nan discussed with the little girl, and agreed not to lock the door, but who used the room, who hung their schoolbags at the door, but their schoolbags were the same style, so every time before entering the door, they had to rummage through the schoolbags to see who the textbooks were, if it was their own, then they could enter the door, so that the province was locked and unlocked. In case the bag is not your own, then wait outside the door and inform the other party to lock the door next time.
Later, the little girl returned to her hometown and would not use this room for a long time. Xiao Nan still hangs his schoolbag every time and flips through his schoolbag, although it is easier than locking the door, but he still feels troublesome.
So, Xiao Nan simply engraved his name on the door: [Xiao Nan's exclusive room, no one else should use it], the next time you come to use the room, as long as the name is still there, then it means that no one disturbs you, and you can still use the room safely. If someone else wants to use this room during this period, then the user will erase Xiao Nan's name and upgrade it to a schoolbag.
The classmates all returned to their hometown for the holidays, and Xiao Nan swelled, carving his name in 20 rooms, and he wanted to enter whichever he wanted. Later, he went back to his hometown on vacation, and at this time the little girl came back (she also had to use these rooms), and the result was that he had to erase Xiao Nanke's name one by one and upgrade to the way of hanging a schoolbag. Lao Wang felt that the cost was a bit high, and proposed a method of batch re-engraving, he let the little girl not have to hang her schoolbag, and she could directly engrave her name on the door.
Later, the phenomenon of engraving names became more and more frequent, and Lao Wang couldn't stand it: forget it, these rooms can't be engraved, and they can only hang schoolbags--- setting up this kind of non-bias.
It is reflected in the section code instruction.Use cases of lightweight locks: If an object has multiple threads to be locked, but the locking time is staggered (i.e., there is no contention), then lightweight locks can be used to optimize.
If there is competition, the lightweight lock is upgraded to a heavyweight lock.
Lightweight locks are transparent to the consumer, i.e. the syntax remains the samesynchronized
Suppose there are two ways to synchronize blocks, locking with the same object.
static final object obj = new object();public static void method1() public static void method2()Create a lock record object, and the stack frame of each thread will contain a lock record structure, which can store the mark word of the lock object
Let the object reference in the lock record point to the lock object, and try to replace the mark word of the object with cas (compare and swap, atomicity), and save the value of the mark word in the lock record.
If the CAS (compare and swap) replacement is successful, the object is stored in the headerThe lock records address and status 00
, which indicates that the thread has locked the object, as shown below.
If CAS(compare and swap) fails, there are two scenarios.
If another thread already holds a lightweight lock on the object, it indicates that there is contention and the lock expansion process begins.
If you do it yourselfsynchronized lock reentrant, then add a lock record as the re-entrancy count, as in the example.
When exiting the synchronized block (when unlocked), if there is a lock record with a value of null, it means that there is a reentriency, and then the lock record is reset, which means that the reentrancy count is minus one (the number of lock reentrants).
When exiting the synchronized block (when unlocked) the value of the lock record is not null, then use CAS (compare and swap, atomicity) to restore the value of the mark word to the object header.
If it is successful, the unlock will be successful.
If it fails, the lightweight lock has been inflated or upgraded to a heavyweight lock, and the heavyweight lock unlocking process has begun.
If the CAS operation fails to succeed in trying to add a lightweight lock, then another thread adds a lightweight lock to the object (there is contention), and the lock expansion is required to turn the lightweight lock into a heavyweight lock.
static object obj = new object();public static void method1()When thread-1 does a lightweight lock, thread-0 already has a lightweight lock on the object.
At this time, thread-1 and lightweight locks fail and enter the lock expansion process.
That is, apply for a monitor lock for the object object, and let the object point to the heavyweight lock address.
Then go into the Monitor's entrylist blocked yourself
When thread-0 exits sync block unlocking, using cas to restore the value of the mark word to the object header fails. At this time, it will enter the heavyweight unlocking process, that is, find the monitor object according to the monitor address, set the owner to null, and wake up the blocked thread in the entrylist.
Spin can also be used to optimize when heavyweight locks are in contention, so that if the current thread spins successfully (i.e., the lock-holding thread has exited the sync block and released the lock), then the current thread can avoid blocking.
A condition in which the spin retry succeeded.
Thread 2 spin retries 3 times to successfully lock so that it doesn't get blocked.
A condition in which the spin retry fails.
Thread 2 is spinning all the time and is finally blocked.
Spin takes up CPU time, single-core CPU spin is waste, and multi-core CPU spin is the advantage.
After J**A 6, the spinlock is adaptive, for example, if the object has just succeeded in a spin operation, then it thinks that the probability of success of the spin will be high, so it spins a few more times;On the contrary, there is less spin or even no spin, in short, it is more intelligent.
j**a 7 After that, you can't control whether the spin function is turned on.
Lightweight locks still need to perform a CAS operation every time the lock is re-entrant when there is no contention (in its own thread).
In J**A 6, biased locking was introduced for further optimization: only the first time you use CAS to set the thread ID to the mark word header of the object, and then find out that the thread ID is your own, it means that there is no contention, and there is no need to re-CAS. In the future, as long as there is no competition, the object is owned by the thread.
For example:
static final object obj = new object();public static void m1() public static void m2() public static void m3()
Recall the object header format.
|--mark word (64 bits) |state | unused:25 | hashcode:31 | unused:1 | age:4 | biased_lock:0 | 01 | normal |Normal |- Biased lock | thread:54 | epoch:2 | unused:1 | age:4 | biased_lock:1 | 01 | biased | ptr_to_lock_record:62 | 00 | lightweight locked |Lightweight |- Heavyweight | ptr_to_he**yweight_monitor:62 | 10 | he**yweight locked | 11 | marked for gc |When an object is created:
If bias lock is enabled (enabled by default), then after the object is created, the markword value is 0x05 that is, the last 3 bits are 101, and its thread, epoch, and age are all 0
The bias lock is delayed by default, and will not take effect immediately when the program starts, you can check it after 4s of sleep, if you want to avoid the delay, you can add the vm parameter-xx:biasedlockingstartupdelay=0
to disable latency.
If bias lock is not enabled, then after the object is created, the markword value is 0x01, that is, the last 3 bits are 001, then its hashcode and age are 0, and the value will be assigned when the hashcode is used for the first time.
class dog {}Utilize JOL third-party tools to view object header information.
pom file.
org.openjdk.jol jol-core 0.10Pay attention to the ** of this subsection to understand it, the machine is not running successfully, just pay attention to the output
Add the VM parameter -xx:biasedlockingstartupdelay=0 public static void main(string args) throws ioexception logdebug("synchronized"); system.out.println(classlayout.toprintable***true));"t1").start();Output.
11:08:58.117 c.testbiased[t1] -synchronized 11:0 00000101 8:58121 c.testbiased [t1] -synchronized 00000000 00000000 00000000 00000000 00000000 00011111 11101011 110100000 00000101 the difference from the output above, look at 11:08:58121 c.testbiased [t1] -synchronized after 00000000 00000000 00000000 00000000 00011111 11101011 11010000 00000101 is in a biased lock, and the thread ID remains unchanged unless there is a new contention
NoteWhen an object that is in a biased lock is unlocked, the thread ID is still stored in the object header.Above the test runtime is adding the VM parameters
-xx:-usebiasedlocking
Disable bias locking.
Output.
11:13:10.018 c.testbiased [t1] -synchronized the first 00000000 000000000 000000000 0000000000 000000000 0000000000 000000000 00000001 The last three digits of the three logs are not 101 11:13:10021 c.testbiased[t1] -synchronized in 00000000 000000000 00000000 00000000 001000000 00010100 11110011 10001000 in lightweight lock 11:13:10021 c.testbiased [t1] -synchronized 000000000 000000000 000000000 00000000000 00 00000001 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004) Test the hashcode and add the VM parameters
-xx:biasedlockingstartupdelay=0
to disable latency.
Normal state objects start without hashcode and are generated on the first call.
Calling hashcode causes bias locks to be disabled. Because if it is in the biased lock state, the thread id has been stored, and then the hashcode is stored, and the space is not enough, so it cannot be stored. So the state will be changed to the normal state at this time. In addition, the hashcode of the lightweight lock is stored in the lock record in the stack frame, and the hashcode of the heavyweight lock is stored in the monitor object, which will be restored when unlocked.
The hashcode of the object is called, but the thread ID is stored in the markword of the lock-biased object, and if the hashcode is called, the bias lock will be revoked.
Lightweight locks record a hashcode in the lock record
Heavyweight locks log a hashcode in the monitor
Use bias locks after calling hashcode, remember to remove them-xx:-usebiasedlocking
Output.
11:22:10.386 c.testbiased [main] - calls hashcode:1778535015 11:22:10391 c.testbiased [t1] -synchronized front 00000000 00000000 00000000 01101010 00000010 01001010 01100111 00000001 11:22:10393 c.testbiased[t1] -synchronized 00000000 000000000 000000000 000000000 001000000 11000011 11110011 01101000 11:22:10393 c.testbiased [t1] -synchronized after 00000000 00000000 000000000 01101010 00000010 01001010 01100111 00000001When other threads use biased lock objects, biased locks are upgraded to lightweight locks.
private static void test2() throws interruptedexception locks the current class object synchronized (testbiased.).class) If you don't use wait notify to use join, you must open the following comment because: the t1 thread cannot be ended, otherwise the underlying thread may be reused by the jvm as a t2 thread, and the underlying thread id is the same *try catch (ioexception e) * },"t1"); t1.start();thread t2 = new thread(()catch (interruptedexception e) log.debug(classlayout.parseinstance(d).toprintable***true));synchronized (d) log.debug(classlayout.parseinstance(d).toprintable***true));"t2"); t2.start();Output.
[t1] -000000000 00000000 00000000 00000000 00011111 01000001 00010000 00000101 is in biased lock [t2] -000000000 00000000 00000000 00011111 01000001 00010000 00000101 T2 thread is not locked and T1 is consistent [T2] -000000000 00000000 000000000 00000000 00011111 10110101 11110000 010000000 in lightweight lock [t2] -000000000 00000000 000000000 0000000000 0000000000 000000000 00000001 is unbiased after unlockingIn this case, the bias lock is also revoked. Because wait notify is only available for heavyweight locks. Biased locks or lightweight locks are upgraded to heavyweight locks.
public static void main(string args) throws interruptedexception catch (interruptedexception e) log.debug(classlayout.parseinstance(d).toprintable***true));"t1"); t1.start();new thread(()catch (interruptedexception e) synchronized (d) "t2").start();Output.
[t1] -000000000 000000000 000000000 000000000 000000000 000000000 00000000 00000101 bias lock [t1] -000000000 000000000 00000000 00011111 10110011 11111000 00000101 lock [t2] -notify [t1] - 00000000 00000000 00000000 000000000 00011100 11010100 00001101 11001010 heavyweight locksIf an object is accessed by multiple threads but does not compete, the object that is biased towards thread t1 still has a chance to re-bias to t2, which resets the object's thread id
When the revocation bias lock threshold exceeds 20 times, the JVM thinks if I'm biased wrong, and re-biases to the locked thread when locking these objects.
private static void test3() throws interruptedexception }synchronized (list) "t1"); t1.start();thread t2 = new thread(()catch (interruptedexception e) log.debug("***"); for (int i = 0; i < 30; i++)log.debug(i + "\t" + classlayout.parseinstance(d).toprintable***true));"t2"); t2.start();Output.
[t1] -0 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 //- Biased lock |t1] -1 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -2 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -3 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -4 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -5 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -6 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -7 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -8 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -9 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -10 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -11 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -12 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -13 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -14 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -15 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -16 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -17 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -18 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -19 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -20 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -21 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -22 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -23 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -24 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -25 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -26 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -27 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -28 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -29 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -t2] -0 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 //Biased to T1 lock [t2] -0 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 //Revoke the bias lock,Upgrade to a lightweight lock [.]t2] -0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 //In the non-bias lock,That is, the normal state [t2] -1 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -1 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -1 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -2 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -2 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -2 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -3 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -3 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -3 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -4 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -4 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -4 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -5 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -5 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -5 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -6 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -6 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -6 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -7 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -7 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -7 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -8 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -8 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -9 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -9 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -9 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -10 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -10 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -10 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -11 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -11 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -11 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -12 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -12 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -12 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -13 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -13 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -13 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -14 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -14 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -14 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -15 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -15 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -15 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -16 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -16 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -16 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -17 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -17 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -17 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -18 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -18 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -18 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -19 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 //The 20th object begins,All are in a biased lock that is biased towards t2 [t2] -19 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 //Batch rebias,All of the latter are biased locks that are biased towards t2t2] -19 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -20 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -20 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -20 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -21 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -21 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -21 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -22 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -22 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -22 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -23 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -23 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -23 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -24 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -24 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -24 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -25 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -25 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -25 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -26 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -26 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -26 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -27 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -27 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -27 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -28 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -28 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -28 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -29 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -29 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -29 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101When the revocation bias lock threshold exceeds 40 times, the JVM feels that it is indeed biased and should not be biased at all. As a result, all objects in the entire class become unbiasable, and the newly created objects are also non-biasable.
I won't print the log here, you can think for yourself.
static thread t1,t2,t3; private static void test4() throws interruptedexception }locksupport.unpark(t2); "t1"); t1.start();t2 = new thread(()log.debug(i + "\t" + classlayout.parseinstance(d).toprintable***true));locksupport.unpark(t3); "t2"); t2.start();t3 = new thread(()log.debug(i + "\t" + classlayout.parseinstance(d).toprintable***true));"t3"); t3.start();t3.join();log.debug(classlayout.parseinstance(new dog())toprintable***true));
@fork(1) @benchmarkmode(mode.**eragetime) @warmup(iterations=3) @measurement(iterations=5) @outputtimeunit(timeunit.nanoseconds) public class mybenchmark @benchmark public void b() throws exception }
j**a -jar benchmarks.jar
benchmark mode samples score score error units c.i.mybenchmark.a **gt 5 1.542 0.056 ns/op c.i.mybenchmark.b **gt 5 1.518 0.091 ns/opB has a locked operation, so why is it almost different from the time taken by A and B?Because there is a JIT (just-in-time compiler) in J**A, it will optimize the repeated execution of **, and the O object in B will not be shared at all, so synchronized in B is meaningless, so J**A will eliminate the lock. This also has a switch, this switch is turned on by default, and the following demonstration will turn this switch off.
j**a -xx:-eliminatelocks -jar benchmarks.jar
benchmark mode samples score score error units c.i.mybenchmark.a **gt 5 1.507 0.108 ns/op c.i.mybenchmark.b **gt 5 16.976 1.572 ns/opYou can see that there is a significant difference in the time required.
Locking the same object multiple times, resulting in multiple reentrants of the thread, can be optimized using lock coarsening, which is different from the previous granularity of subdivision locks.
Author:|Old City Scavenging|
*:cnblogs.com/xiaoyh/p/17157540.html