Talking about the mechanism of multithreading lock

Keywords: Java jvm

Lock mechanism in Java

synchronized - The keyword of the Java language, when used to modify a method or block of code, ensures that at most one thread executes the code at the same time.

  1. When two concurrent threads access this synchronized synchronized block of code in the same object Object, only one thread can be executed in one time. Another thread must wait for the current thread to execute the code block before it can execute the code block.
  2. However, when one thread accesses a synchronized block of synchronized code in Object, another thread can still access a non-synchronized block of synchronized code in Object.
  3. Especially critical is that when a thread accesses a synchronized block of Object, other threads will block access to all other synchronized blocks in Object. That is to say, when a thread accesses a synchronous block of code in Object, it obtains the object lock of the Object. As a result, access to all synchronization code parts of the Object object is temporarily blocked by other threads.

Note: This can only be used in method headers (after qualifying modifiers public and private, before returning values void and Object) and within methods.
Example 1:

public class ThreadTest {
    public static void main(String[] args) {
        final SynchronizedTest test=new SynchronizedTest();
        //Thread 1
          Thread thread1=new Thread(new Runnable() {
              @Override
              public void run() {
                test.test("thread1");
              }
          });
        //Thread 2
        Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
           test.test("thread2");
            }
        });

        thread1.start();
        thread2.start();
    }
}
public class SynchronizedTest {

    public synchronized void test(String name){
        for(int i=0;i<5;i++){
            System.out.println(name+"Function");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
 }

Print results
thread1 runs
thread1 runs
thread1 runs
thread1 runs
thread1 runs
thread2 runs
thread2 runs
thread2 runs
thread2 runs
thread2 runs
Example 2: Two concurrent threads call a synchronous method and a common method

 //Thread 2
        Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                test.test3("thread2");//Above is the test method
            }
        });

        //A New Common Method in SynchronizedTest Class
   public void test3(String name){
        for(int i=0;i<5;i++){
            System.out.println(name+"Function");

        }
    }
    /*Operation result
    thread1 Function
thread2 Function
thread2 Function
thread2 Function
thread2 Function
thread2 Function
thread1 Function
thread1 Function
thread1 Function
thread1 Function*/

Example 3:

//Thread 2
        Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                test.test3("thread2");//Above is the test method
            }
        });
//New SynchronizedTest Class SynchronizedTest 2
public synchronized void test2(String name){
        for(int i=0;i<5;i++){
            System.out.println(name+"Function");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
/*Operation result
thread1 Function
thread1 Function
thread1 Function
thread1 Function
thread1 Function
thread2 Function
thread2 Function
thread2 Function
thread2 Function
thread2 Function*/

Method Lock (synchronized modification method)

The synchronized method is declared by adding the synchronized keyword to the method declaration.

The synchronized method controls access to class member variables:
Each class instance corresponds to a lock, and each synchronized method must obtain the lock of the class instance invoking the method before it can execute. Otherwise, the thread to which it belongs will block. Once the method executes, it will monopolize the lock until it returns from the method, and then the blocked thread will get the lock and re-enter the executable state. This mechanism ensures that at most one member function declared synchronized is executable for each class instance at the same time, thus effectively avoiding the access conflict of class member variables.

Object locks (synchronized modifiers or blocks of code)

When an object has synchronized method or synchronized block, it must first acquire the object lock when it calls the synchronized method of the object or enters its synchronized region. If the object lock of this object has been occupied by other callers, you need to wait for the lock to be released. (Method locks are also object locks)
  
All objects in java contain a mutex, which is automatically acquired and released by the JVM. When a thread enters the synchronized method, it acquires the lock of the object. Of course, if a thread has acquired the lock of the object, the current thread will wait. When the synchronized method returns normally or terminates by throwing an exception, the JVM will automatically release the lock of the object. This also shows the advantage of synchronized locking. When the method throws an exception, the lock can still be released automatically by the JVM.  

Two forms of object lock:

public class Test
{
    // Object Locks: Form 1 (Method Locks)
    public synchronized void Method1()
    {
        System.out.println("I am an object lock and a method lock.");
        try
        {
            Thread.sleep(500);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }

    }

    // Object Locks: Form 2 (Block Form)
    public void Method2()
    {
        synchronized (this)
        {
            System.out.println("I am an object lock");
            try
            {
                Thread.sleep(500);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }

    }
 }

Class locks (synchronized modifies static methods or blocks of code)

Because no matter how many instances a class is instantiated, there is only one static method and one static variable in memory. So once a static method is declared synchronized. All instantiated objects of this class are calling this method and share the same lock, which we call class lock.  
  
Object locks are used to control synchronization between instance methods, and class locks are used to control synchronization between static methods (or static variable mutexes).  
  
Class lock is only a conceptual thing, not a real thing, it is used to help us understand the difference between locking instance method and static method.  
The java class may have many objects, but only one Class object, that is to say, the Class objects of the class are shared among different instances of the class. Class object is actually just a java object, just a little special. Since each java object has a mutex, the static method of a class requires a Class object. So the so-called class lock is just the lock of the Class object. There are several kinds of Class objects to get classes, the simplest way is to get the class name.class.

public class Test
{
   // Class lock: Form 1
    public static synchronized void Method1()
    {
        System.out.println("I'm Class Lock 1.");
        try
        {
            Thread.sleep(500);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }

    }

    // Class lock: Form 2
    public void Method2()
    {
        synchronized (Test.class)
        {
            System.out.println("I'm Class Lock 2.");
            try
            {
                Thread.sleep(500);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }

        }

    }
}

Posted by KissMyBrain on Sat, 23 Mar 2019 17:48:52 -0700