Basic use of internal lock synchronized

Basic use of synchronized

For threads, if multiple threads are only executed separately from each other, it does not make much sense in itself. Generally speaking, multiple threads are required to cooperate with each other to perform work. Such use will affect the system. Bring practical meaning.
​ In Java, multiple threads are supported to access an object or member variables in an object at the same time, but if there is no protection mechanism, data inconsistency will occur. The effect is as follows:

public class TestThread {
    
    
    public static void main(String[] args) {
    
    
        TestThread testThread = new TestThread();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                testThread.print();
            }
        }).start();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                testThread.print();
            }
        }).start();
    }
    public void print(){
    
    
        for(int i=0;i<1000;i++){
    
    
            System.out.println(Thread.currentThread().getName()+"--->"+i);
        }
    }
}

Insert picture description here

If you want to solve this problem now, you can use a lock to solve it. Synchronized can modify the method or use it in the form of synchronization block. It mainly ensures that multiple threads can only be in the method or synchronization block at the same time. It ensures the visibility and exclusivity of thread access to variables. Also known as the built-in lock mechanism.

Object lock

If a thread that owns the same object lock in a synchronized code block (or synchronization method), if one thread acquires the lock, other threads can only acquire the lock after the thread releases the lock.

this lock object

public class TestThread {
    
    
    public static void main(String[] args) {
    
    
        TestThread testThread = new TestThread();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                testThread.print();
            }
        }).start();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                testThread.print();
            }
        }).start();
    }
    //同步代码块
    public void print(){
    
    
        synchronized (this){
    
    
            for(int i=0;i<1000;i++){
    
    
                System.out.println(Thread.currentThread().getName()+"--->"+i);
            }
        }
    }
         //同步方法,synchronized 默认this作为锁对象
         /* public synchronized void print(){
            for(int i=0;i<1000;i++){
                System.out.println(Thread.currentThread().getName()+"--->"+i);
            }
    }*/
}

Insert picture description here

Constant lock object

public class TestThread {
    
    
    public static void main(String[] args) {
    
    
        TestThread testThread = new TestThread();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                testThread.print();
            }
        }).start();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                testThread.print();
            }
        }).start();
        //调用静态方法
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                TestThread.print2();
            }
        }).start();
    }
    private static final Object obj = new Object();
    public void print(){
    
    
        synchronized (obj){
    
    
            for(int i=0;i<1000;i++){
    
    
                System.out.println(Thread.currentThread().getName()+"--->"+i);
            }
        }

    }
    
    public static void print2(){
    
    
        synchronized (obj){
    
    
            for(int i=0;i<1000;i++){
    
    
      System.out.println(Thread.currentThread().getName()+"--->"+i);
            }
        }
    }
}

Class lock

Synchronize the runtime class as a lock when modifying a static method


public class TestThread {
    
    
    public static void main(String[] args) {
    
    
        TestThread testThread = new TestThread();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                testThread.print();
            }
        }).start();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                testThread.print2();
            }
        }).start();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                TestThread.print2();
            }
        }).start();
    }
    //将TestThread的字节码文件作为锁对象
    public synchronized void print(){
    
    
        synchronized (TestThread.class){
    
    
            for(int i=0;i<1000;i++){
    
    
                System.out.println(Thread.currentThread().getName()+"--->"+i);
            }
        }

    }
    //synchronized修饰静态方法 
    public static synchronized void print2(){
    
    
            for(int i=0;i<1000;i++){
    
    
             System.out.println(Thread.currentThread().getName()+"--->"+i);
            }
    }
}

The above three methods all use the bytecode file of TestThread as the lock object, so synchronization can also be achieved

Lock reentrancy

If the current thread already owns the lock object, the same lock object can be acquired again and again without deadlock.

public class Reentrant {
    
    

    public synchronized void function1(){
    
    
        System.out.println("同步方法1");
        function2();
    }
    public synchronized void function2(){
    
    
        System.out.println("同步方法2");
        function3();
    }
    public synchronized void function3(){
    
    
        System.out.println("同步方法3");
    }

    public static void main(String[] args) {
    
    
        Reentrant reentrant = new Reentrant();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                reentrant.function1();
            }
        }).start();
    }
}

Guess you like

Origin blog.csdn.net/weixin_45742032/article/details/109989626