This article is participating in the “Java Theme Month – Java Brush questions punch card”, see the activity link for details
Syncchronized faults:
- Do not use large blocks of code
- The lock object cannot be empty
- Deadlocks need to be avoided
How to choose Syncchronized and Lock:
- If you can use neither, use the various utility classes in Javautil
- If the keywords are applicable, apply them first and reduce the amount of code
- If you can only lock, lock.
Consider:
- Multiple threads wait for the same Syncchronized. How does the JVM select the next thread to acquire the lock?
- Is blocked
- I was just applying for a lock
- Syncchronized performance optimization
- Reduce the range of locks that apply
- Using read/write locks
- More flexible lock acquisition and release
- The reference code codes itself
What is the upgrade and downgrade of locks
Synchronized blocks are implemented by a pair of Monitorenter/Monitorexit directives, and Monitor objects are the basic implementation units of synchronization. Prior to Java 6, the implementation of Monitor relied entirely on the operating system’s internal mutex, and synchronization was an undifferentiated heavyweight operation because of the need to switch from user to kernel mode. In the modern (Oracle) JDK, the JVM takes a drastic step forward with three different Monitor implementations, often referred to as Biased Locking, lightweight Locking, and heavyweight Locking, which greatly improves performance. The so-called upgrade and degradation of lock is the mechanism by which JVM optimizes synchronized operation. When JVM detects different competition conditions, it will automatically switch to the appropriate lock implementation, which is the upgrade and degradation of lock. Deflection locks are used by default when no race is present. The JVM uses the CAS operation (compare and Swap) to set the thread ID in the Mark Word section of the object’s head to indicate that the object is biased towards the current thread, so no true mutex is involved. This is based on the assumption that in many application scenarios, most objects will be locked by at most one thread during their lifetime, and using skew locks can reduce uncontested overhead. If another thread tries to lock an object that has been skewered, the JVM needs to revoke the skew lock and switch to a lightweight lock implementation. The lightweight lock relies on the CAS operation Mark Word to attempt to obtain the lock. If the retry succeeds, the normal lightweight lock is used. Otherwise, upgrade to a heavyweight lock. I’ve noticed that some people think that Java doesn’t do lock degradation. In fact, as far as I know, lock degradation does occur, and when the JVM enters a SafePoint, it checks for idle Monitors and tries to degrade them.