7 cases of multithreaded and concurrent-multithreaded access synchronization methods

Posted by jaapoost on Wed, 15 Sep 2021 05:50:32 +0200

Don't be tedious, let's get started!

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

Code:

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

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

    public synchronized void method() {
        System.out.println("The method modifier form for object locks, which I call:" + Thread.currentThread().getName());
        try {
            System.out.println(Thread.currentThread().getName() + " Hibernate for 3 seconds");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "End of run");

    }

    public static void main(String[] args) {
        //Synchronization method for two threads accessing an object, an instance instance
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

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

Run result:

The method modifier form for object locks, which I call: Thread-0
Thread-0 Hibernate for 3 seconds
Thread-0 End of run
 The method modifier form for object locks, which I call: Thread-1
Thread-1 Hibernate for 3 seconds
Thread-1 End of run
fininshed

Resolution: Need to contend for the same lock this, so execute sequentially.

2. Two threads access the synchronization method of two objects

Code:

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

    @Override
    public void run() {
        // Current object as lock
        synchronized (this) {
            System.out.println("I'm a block of code for object locks. 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) {
        //Two threads access the synchronization method of two objects, one instance1 and the other instance2
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

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

Run result:

I'm a block of code for object locks. My name is Thread-0
 I'm a block of code for object locks. My name is Thread-1
Thread-1 End of run
Thread-0 End of run
fininshed

Parsing: Parallel processing, no interference, lock instances are not the same.

3. Two threads access the static method of Synchronized

Code:

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

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

    public static synchronized void method(){
        System.out.println("I'm a form of class lock. My name is"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"Thread End");
    }
    
    public static void main(String[] args){
        //Static method for synchronized access by two threads
        Thread t1=new Thread(instance1);
        Thread t2=new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){
        }
        System.out.println("fininshed");
    }
}

Run result:

I'm a form of class lock. My name is Thread-0
Thread-0 Thread End
 I'm a form of class lock. My name is Thread-1
Thread-1 Thread End
fininshed

Resolution: The corresponding locks are executed one by one in the same order.

4. Access synchronous and asynchronous methods simultaneously

Code:

public class SynchronizedYesOrNo implements Runnable {
    static SynchronizedYesOrNo instance=new SynchronizedYesOrNo();
    public static void main(String[] args) {
        Thread th1=new Thread(instance);
        Thread th2=new Thread(instance);
        th1.start();
        th2.start();
        while(th1.isAlive()||th2.isAlive()){

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

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

    public synchronized void method1(){
        System.out.println("I added sync method"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"End");
    }

    public synchronized static void method2(){
        System.out.println("Did I add a sync method?"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"End");

    }
}

Run result:

I added sync method Thread-0
 Did I add a sync method? Thread-1
Thread-0 End
Thread-1 End
finished

Resolution: Synchronous methods will not have concurrency problems, asynchronous methods will not be affected, and concurrency problems will occur.

5. Different common synchronization methods for accessing the same object

Code:

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

    @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"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"End of thread execution");
    }

    public synchronized void method2(){
        System.out.println("I'm also the way to lock"+Thread.currentThread().getName()+"End of thread execution");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"End of thread execution");
    }

    public static void main(String[] args) throws InterruptedException{
        Thread t1=new Thread(instance);
        Thread t2=new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){}
        System.out.println("fininshed");
    }
}

Run result:

I'm the way to lock Thread-0
Thread-0 End of thread execution
 I'm also the way to lock Thread-1 End of thread execution
Thread-1 End of thread execution
fininshed

Parse: Get this lock, so it will still be affected, serial execution.

6. Access both static and non-static synchronized

Code:

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

    @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 method of locking 1 "+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"End of thread execution");
    }

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

    public static void main(String[] args) throws InterruptedException{
        Thread t1=new Thread(instance);
        Thread t2=new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){}
        System.out.println("fininshed");
    }
}

Run result:

I am the static method of locking 1 Thread-0
 I am the non-static method of locking 2 Thread-1
Thread-1 End of thread execution
Thread-0 End of thread execution
fininshed

Resolution: method1 locks the.class object, method2 locks the this object, locks are different, no conflicts, parallel execution.

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

Code:

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

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

    }

    public synchronized void method1() {
        /*
        // Throw Exception
        System.out.println("I am the static method of locking 1 "+ Thread.currentThread().getName()";
        try {
            Thread.sleep(3000);
            //When an exception is thrown, the JVM automatically releases the lock for you, instead of releasing the lock manually by itself.
            throw new Exception();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + ""End of thread execution";
        */

        // Throw RuntimeException
        System.out.println("I am the static method of locking 1" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //When an exception is thrown, the JVM automatically releases the lock for you, instead of releasing the lock manually by itself.
        throw new RuntimeException();
        // System.out.println(Thread.currentThread().getName()+ "End of Thread Execution");
    }

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

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {
        }
        System.out.println("fininshed");
    }
}

Run result:

I am the static method of locking 1 Thread-0
Exception in thread "Thread-0" java.lang.RuntimeException
	at com.interview.javabasic.thread.a0914.SynchronizedException.method1(SynchronizedException.java:50)
	at com.interview.javabasic.thread.a0914.SynchronizedException.run(SynchronizedException.java:16)
	at java.lang.Thread.run(Thread.java:748)
I am also the non-static method of locking 2 Thread-1
Thread-1 End of thread execution
fininshed

Resolution: The lock is released after the method throws an exception.

Summary:

  1. A lock can only be acquired by one thread at the same time, threads that do not get the lock must wait (corresponding to 1,5 questions)
  2. Each instance has its own lock, with no effect between different instances except when the lock object is *.class and synchronized modifies the static method, all objects share a single class lock (corresponding, 2, 3, 4, 6)
  3. Whether the method completes its normal execution or the method throws an exception, the lock is released.
  4. The synchronized method is currently entered, in which the method without the synchronized modification is called. Is it still thread-safe? (Not thread-safe, synchronized can be called by multiple threads at the same time.)

Reference article:

Don't be tedious, end the article, suggest three series!

Topics: Java Multithreading thread