[Java] 7 scenarios for multithreaded access synchronization methods

Seven scenarios for multithreaded access synchronization methods

Preface

synchronized has two uses: object lock and class lock.
Object locks are divided into method locks (the default lock object is this) and synchronous code block locks.
Class locks are divided into locks that modify static methods and locks that are specified as class objects.
Class locks are essentially class object locks. Java classes may have many objects, but only one class object.

1. Synchronization method for two threads accessing an object at the same time

public class SynchronizedObjectMethod3 implements Runnable {
    static SynchronizedObjectMethod3 instance = new SynchronizedObjectMethod3();

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()){

        }
        System.out.println("finished");
    }
    @Override
    public void run() {
        method();
    }

    public synchronized void method(){
        System.out.println("Method modifier form of my object lock,My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run");
    }
}

Two threads are competing for the same lock, so the thread is serial execution.
The results are:

The method modifier form of my object lock is Thread-0
 End of Thread-0 run
 The method modifier form of my object lock is Thread-1
 End of Thread-1 run
finished

2. Static methods for two threads to access two objects

public class SynchronizedObjectCodeBlock2 implements Runnable{
    static SynchronizedObjectCodeBlock2 instance1 = new SynchronizedObjectCodeBlock2();
    static SynchronizedObjectCodeBlock2 instance2 = new SynchronizedObjectCodeBlock2();
    Object lock1 = new Object();
    Object lock2 = new Object();

    @Override
    public void run() {
        synchronized (this){
            System.out.println("I am lock1. My name is" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() +" lock1 Partial Run End.");
        }

//        synchronized (lock2){
//            System.out.println("I am lock2.My name" + Thread.currentThread().getName()));
//            try {
//                Thread.sleep(3000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println (Thread.currentThread().getName()+ "lock2 partial run end");
//        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()){

        }
        System.out.println("finished");
    }
}

At this point, the two threads are competing for different locks, synchronized does not work.

I'm lock1. My name is Thread-0
 I'm lock1. My name is Thread-1
 The Thread-0 lock1 section ends.
The Thread-1 lock1 section ended.
finished

3. Both threads access the synchronized static method

public class SynchronizedClassStatic4 implements Runnable{
    static SynchronizedClassStatic4 instance1 = new SynchronizedClassStatic4();
    static SynchronizedClassStatic4 instance2 = new SynchronizedClassStatic4();

    @Override
    public void run() {
        method();
    }

    public static synchronized void method(){
        System.out.println("I am the first form of class lock:static form.My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run.");
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);
        t1.start();
        t2.start();
        while(t1.isAlive() || t2.isAlive()){

        }
        System.out.println("finished");
    }
}

The results are:

I'm the first form of a class lock: static. My name is Thread-0
 End of Thread-0 run.
I'm the first form of a class lock: static. My name is Thread-1
 End of Thread-1 run.
finished

4. Access synchronous and asynchronous methods simultaneously

public class SynchronizedYesAndNo6 implements Runnable{
    static SynchronizedYesAndNo6 instance = new SynchronizedYesAndNo6();

    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")){
            method1();
        } else {
            method2();
        }
    }

    public synchronized void method1(){
        System.out.println("I'm the way to lock.My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run");
    }

    public void method2(){
        System.out.println("Am I the way to lock.My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run");
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while(t1.isAlive() || t2.isAlive()){

        }
        System.out.println("finished");
    }
}

The synchronized modification of one method does not affect the concurrency of the other.Asynchronous methods are not affected by synchronous methods.

I'm the way to lock. My name is Thread-0
 I have no lock method. My name is Thread-1
 End of Thread-0 run
 End of Thread-1 run
finished

5. Different common synchronization methods for accessing the same object

public class SynchronizedDifferentMethod7 implements Runnable{
    static SynchronizedDifferentMethod7 instance = new SynchronizedDifferentMethod7();

    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")){
            method1();
        } else {
            method2();
        }
    }

    public synchronized void method1(){
        System.out.println("I'm locking method 1.My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run");
    }

    public synchronized void method2(){
        System.out.println("I'm locking method 2.My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run");
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while(t1.isAlive() || t2.isAlive()){

        }
        System.out.println("finished");
    }

}

At this point, the this object is designated as the lock, which is the same for the same instance.

I'm the way to lock 1. My name is Thread-0
 End of Thread-0 run
 I'm the way to lock 2. My name is Thread-1
 End of Thread-1 run
finished

6. Access both static and non-static synchronized methods

public class SynchronizedStaticAndNormal8 implements Runnable{
    static SynchronizedStaticAndNormal8 instance = new SynchronizedStaticAndNormal8();

    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")){
            method1();
        } else {
            method2();
        }
    }

    public synchronized static void method1(){
        System.out.println("I am the static lock method 1.My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run");
    }

    public synchronized void method2(){
        System.out.println("I am the method of non-static locking 2.My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run");
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while(t1.isAlive() || t2.isAlive()){

        }
        System.out.println("finished");
    }
}

These two methods can be executed in parallel.The lock of the static locking method is the class object, and the lock object of the non-static locking method is the this object.The two methods are not competing for the same lock.

I'm the static lock method 1. My name is Thread-0
 I'm a non-static lock method 2. My name is Thread-1
 End of Thread-0 run
 End of Thread-1 run
finished

7. The lock will be released after the method throws an exception

/**
 * The lock is released when the method throws an exception
 * Show a comparison before and after throwing an exception
 * Once an exception is thrown
 * The second thread immediately enters the synchronization method
 * Means the lock has been released
 */
public class SynchronizedException9 implements Runnable{
    static SynchronizedException9 instance = new SynchronizedException9();

    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")){
            method1();
        } else {
            method2();
        }
    }

    public synchronized void method1(){
        System.out.println("I'm locking method 1.My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        throw new RuntimeException();
//        System.out.println(Thread.currentThread().getName()+ "Run End");
    }

    public synchronized void method2(){
        System.out.println("I'm locking method 2.My name is" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run");
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while(t1.isAlive() || t2.isAlive()){

        }
        System.out.println("finished");
    }
}
I'm the way to lock 1. My name is Thread-0
 Exception in thread "Thread-0" I am the method of locking 2.My name is Thread-1
java.lang.RuntimeException
	at com.interview.javabasic.thread.SynchronizedException9.method1(SynchronizedException9.java:29)
	at com.interview.javabasic.thread.SynchronizedException9.run(SynchronizedException9.java:16)
	at java.lang.Thread.run(Thread.java:748)
End of Thread-1 run
finished

54 original articles published, acclaimed 11, visited 6445
Private letter follow

Tags: Java

Posted on Thu, 13 Feb 2020 19:48:43 -0800 by jdorsch