Similarities and differences between synchronized and Lock


1. Similarities and differences between synchronized and Lock

Both synchronized and Lock can be locked, but the difference is that Synchronized is a keyword in Java, and Lock is an interface under the java.util.concurrent.Locks package, and there are different implementation methods underneath. In addition, synchronized can be used on code blocks and methods; while Lock can only be written in code.


Synchronized automatically releases the lock when the code is executed or an exception occurs; Lock does not automatically release the lock, and the release lock needs to be displayed in finally . The implementation of Lock makes the locking behavior more flexible, can respond to interrupts, and can determine whether the lock has been acquired, while the synchronized keyword does not have these behaviors.

public class Test01 {
    
    
    private static final ReentrantLock lock = new ReentrantLock();
    public static void main(String[] args){
    
    
        try {
    
    
            // 获取锁
            lock.lock();
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            // 释放锁
            lock.unlock();
        }
    }
}

2. The underlying implementation principle of synchronized

1. When synchronized acts on a code block, its bottom layer is realized through the monitorenter and monitorexit instructions.

  • monitorenter:
    Each object is a monitor lock (monitor). When the monitor is occupied, it will be in the locked state.
    When the thread executes the monitorenter instruction, it tries to acquire the ownership of the monitor. The process is as follows:
    if the number of monitor entries is 0, the The thread enters the monitor, and then sets the number of entries to 1, and the thread is
    the owner of the monitor. If the thread already occupies the monitor and just re-enters, the number of entries into the monitor is increased by 1. If
    other threads have already occupied the monitor, the thread enters the blocking state until the number of monitor entries is 0, and then tries to acquire the
    ownership of the monitor again.
  • monitorexit:
    The thread that executes monitorexit must be the monitor holder corresponding to the objectref. When the instruction is executed, the entry number of the monitor
    is decremented by 1. If the entry number is 0 after decrementing 1, the thread exits the monitor and is no longer the owner of the monitor. Other
    threads blocked by this monitor can try to take ownership of this monitor.

2. Method synchronization is not completed through monitorenter and monitorexit instructions, but compared with ordinary methods, there are
more ACC_SYNCHRONIZED identifiers in its constant pool. The JVM implements method synchronization based on this identifier:

When the method is called, the call instruction will check whether the ACC_SYNCHRONIZED access flag of the method is set. If it is set, the execution thread will first acquire the monitor, and then execute the method body after the acquisition is successful, and then release the monitor after the method is executed. During method execution, no other thread can get the same monitor object again.

3. Can synchronized modify static methods and static code blocks?

synchronized can modify static methods, but not static code blocks.
When modifying a static method, the monitor lock (monitor) is the Class instance of the object, because the Class data exists in the permanent generation, so the
static method lock is equivalent to a global lock of the class.

Fourth, the realization principle of ReentrantLock

ReentrantLock is implemented based on AQS, which is the abbreviation of AbstractQueuedSynchronizer. Specifically, take a look at AbstractQueuedSynchronizer, the soul of Java concurrent contract delivery

Guess you like

Origin blog.csdn.net/weixin_44153131/article/details/129785304