How does lock achieve multi-thread synchronization and under what circumstances will it become invalid?

How should lock objects be declared? Is it a global variable or is it a local variable declared in a code block that needs to be synchronized?

With this question in mind, I actually did it myself. The code is as follows:

The first case: lock is a global variable, and the class where the method that needs to be synchronized is always created new when used.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestLock {
    Lock lock = new ReentrantLock();
    public void test1(String name){
// Lock lock = new ReentrantLock();
        System.out.println("lock:" + lock.hashCode());
        lock.lock();
        for (int i = 0; i < 100; i + + ) {
            System.out.println("Current thread==========" + name + ":" + i);
        }
        lock.unlock();
    }

    public static void main(String[] args) {
// TestLock testLock = new TestLock();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                TestLock testLock = new TestLock();
                testLock.test1(Thread.currentThread().getName());
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                TestLock testLock = new TestLock();
                testLock.test1(Thread.currentThread().getName());
            }
        });

        thread1.start();
        thread2.start();
    }
}

Running result: The lock objects are not the same, and multi-thread synchronization cannot be achieved.

The second case: the lock object is always newly created, and the object of the class where the synchronization method is located is the same

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestLock {
// Lock lock = new ReentrantLock();
    public void test1(String name){
        Lock lock = new ReentrantLock();
        System.out.println("lock:" + lock.hashCode());
        lock.lock();
        for (int i = 0; i < 100; i + + ) {
            System.out.println("Current thread==========" + name + ":" + i);
        }
        lock.unlock();
    }

    public static void main(String[] args) {
        TestLock testLock = new TestLock();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
// TestLock testLock = new TestLock();
                testLock.test1(Thread.currentThread().getName());
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
// TestLock testLock = new TestLock();
                testLock.test1(Thread.currentThread().getName());
            }
        });

        thread1.start();
        thread2.start();
    }
}

Running result: The lock objects are not the same, and multi-thread synchronization cannot be achieved.

The third case: both are always new

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestLock {
// Lock lock = new ReentrantLock();
    public void test1(String name){
        Lock lock = new ReentrantLock();
        System.out.println("lock:" + lock.hashCode());
        lock.lock();
        for (int i = 0; i < 100; i + + ) {
            System.out.println("Current thread==========" + name + ":" + i);
        }
        lock.unlock();
    }

    public static void main(String[] args) {
// TestLock testLock = new TestLock();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                TestLock testLock = new TestLock();
                testLock.test1(Thread.currentThread().getName());
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                TestLock testLock = new TestLock();
                testLock.test1(Thread.currentThread().getName());
            }
        });

        thread1.start();
        thread2.start();
    }
}

Running result: The lock objects are not the same, and multi-thread synchronization cannot be achieved.

The fourth situation: Both guarantee that the same object is obtained in multi-threading situations.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestLock {
    Lock lock = new ReentrantLock();
    public void test1(String name){
// Lock lock = new ReentrantLock();
        System.out.println("lock:" + lock.hashCode());
        lock.lock();
        for (int i = 0; i < 100; i + + ) {
            System.out.println("Current thread==========" + name + ":" + i);
        }
        lock.unlock();
    }

    public static void main(String[] args) {
        TestLock testLock = new TestLock();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
// TestLock testLock = new TestLock();
                testLock.test1(Thread.currentThread().getName());
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
// TestLock testLock = new TestLock();
                testLock.test1(Thread.currentThread().getName());
            }
        });

        thread1.start();
        thread2.start();
    }
}

Running results: Multi-thread synchronization is achieved

After actual testing, lock synchronization requires the simultaneous acquisition of the lock object and the object instance that requires synchronization code. The two instance objects obtained by multi-threads must be the same, otherwise synchronization cannot be achieved.

To achieve multi-thread synchronization, we only need the lock object to be the same. Why do we need to ensure that the object of the class where the synchronization method is located is also the same?
The prerequisite for the lock to take effect is that in multi-threading, all threads get the same lock object; the lock object is a global variable of the class where the synchronization method is located. If the objects of the class where the synchronization method is located are not the same, the lock objects obtained are also different. one.

The above is all personal understanding, please feel free to comment if there is anything wrong.

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java skill treeNIOFile Lock 137737 people are learning the system