Phenomena and Interpretation of JUC-Lock

Thread Operations Resource Class, 8 Lock Case Description

1. Standard access has ab threads. Would you like to print mail or text messages first?

class Phone {
    public synchronized void sendMail() {
        System.out.println("===>sendMail");
    }
    public synchronized void sendSms() {
        System.out.println("===>sendSms");
    }
}
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(phone::sendMail,"A thread").start();
        new Thread(phone::sendSms,"B thread").start();
    }

===>sendMail
===>sendSms

2. sendEmail method pauses for 3 seconds. Would you like to print the mail or text message first?

class Phone {
    public synchronized void sendMail() {
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("===>sendMail");
    }
    public synchronized void sendSms() {
        System.out.println("===>sendSms");
    }
}

===>sendMail
===>sendSms

The conclusion from 1 and 2 is that if there are multiple synchronized methods in an object, only one thread can call one of them at a time, and all other threads can wait. In other words, only one thread can access these synchronized methods at a time, and the current object is locked(Threads A and b use the same lock instead of the synchronized method), once locked, no other thread can enter the other synchronized methods of the current object.

3. Add a new common Hello method. Would you like to print the email or hello first?

class Phone {
    public synchronized void sendMail() {
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("===>sendMail");
    }
    public synchronized void sendSms() {System.out.println("===>sendSms");}
    public void hello() {System.out.println("===>hello");}
}
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(phone::sendMail,"A thread").start();
        new Thread(phone::hello,"B thread").start();
    }

===>hello
===>sendMail

Conclusion: The general method is not related to synchronization lock, so hello executes first.

4. There are 2 Mobile Resource classes. Would you like to print mail or text messages first?

    public static void main(String[] args) {
        Phone phoneA = new Phone();
        Phone phoneB = new Phone();
        new Thread(phoneA::sendMail,"A thread").start();
        new Thread(phoneB::hello,"B thread").start();
    }

===>sendSms
===>sendMail

Conclusion: Threads a and b are not the same lock.

5. Two static synchronization methods, one resource class. Would you like to print mail or text messages first?

class Phone {
    public static synchronized void sendMail() {
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("===>sendMail");
    }
    public static synchronized void sendSms() {System.out.println("===>sendSms");}
}
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(() -> phone.sendMail(),"A thread").start();
        new Thread(() -> phone.sendSms(),"B thread").start();
    }

===>sendMail
===>sendSms

6. Two static synchronization methods and two resource classes. Would you like to print mail or text messages first?

    public static void main(String[] args) {
        Phone phoneA = new Phone();
        Phone phoneB = new Phone();
        new Thread(() -> phoneA.sendMail(),"A thread").start();
        new Thread(() -> phoneB.sendSms(),"B thread").start();
    }

===>sendMail
===>sendSms

The conclusion from 5 and 6 is that for a normal synchronization method, the lock is the current instance object, usually referring to this, a specific mobile phone, all the common synchronization methods use the same lock - the instance object itself, that is, the object lock. For a static synchronization method, the lock is the Class object of the current class, such as the only template of Phone.class, which calls the static synchronization methodThreads use the same lock, a class lock. For synchronized method blocks, the lock is an object in synchronized parentheses.

7. A static synchronization method, a common synchronization method, and a resource class. Would you like to print mail or text messages first?

class Phone {
    public static synchronized void sendMail() {
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("===>sendMail");
    }
    public synchronized void sendSms() {System.out.println("===>sendSms");}
}
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(Phone::sendMail,"A thread").start();
        new Thread(phone::sendSms,"B thread").start();
    }

 ===>sendSms
===>sendMail

Two different locks, one class lock, one object lock

8. One static synchronization method, one common synchronization method and two resource classes. Would you like to print mail or text messages first?

    public static void main(String[] args) {
        Phone phoneA = new Phone();
        Phone phoneB = new Phone();
        new Thread(()->phoneA.sendMail(),"A thread").start();
        new Thread(phoneB::sendSms,"B thread").start();
    }

===>sendSms
===>sendMail

Two different locks, one class lock, one object lock

Summary

When a thread attempts to access synchronous code, it must first be locked, and when it exits or throws an exception, it must release the lock.

All common synchronization methods use the same lock - the instance object itself, the new specific instance object itself, this class. That is, if a common synchronization method of an instance object acquires a lock, the other common synchronization methods of the instance object must wait for the lock acquisition method to release the lock before acquiring the lock.

All static synchronization methods use the same lock, the class object itself, which is the only template Class we've said. The specific instance objects this and the unique template Class, which are two different objects, so there is no race condition between the static synchronization method and the normal synchronization method. But once a static synchronization method acquires a lock, the other static synchronization methods do not race.Synchronization methods must wait for the method to release the lock before they can acquire it.

Acts on the common synchronization method, the current instance is locked, and the lock of the current instance is acquired before entering the synchronization method.

Acts on synchronous code blocks to lock objects configured within parentheses;

Acts on a static synchronization method, the current class locks, and acquires the lock on the current object before entering the synchronization method.

Tags: Java Interview Multithreading

Posted on Sat, 25 Sep 2021 12:06:33 -0400 by jjacquay712