Multithreading (3) 8 questions about locks

1. Under standard circumstances, which of the two threads prints first

Using synchronized locks

public class Test1 {
    
    
    public static void main(String[] args) {
    
    
        Phone phone = new Phone();
        new Thread(()->{
    
    phone.sendSms();},"A").start();

        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        new Thread(()->{
    
    phone.call();},"B").start();
    }
}
class Phone{
    
    
    //synchronized锁的对象是方法的调用者
    //都是phone,因为用的同一把锁,所以谁先拿到谁先执行
    public synchronized void sendSms(){
    
    
        System.out.println("发短信");
    }
    public synchronized void call(){
    
    
        System.out.println("打电话");
    }

}

insert image description here
Send a text message first and then make a call
because
the object of the synchronized lock is the caller of the method. The objects of Test1 are all phones. Because the same lock is used, whoever gets it first executes it first.

2. The delay of sendSms is four seconds, the order of execution

public synchronized void sendSms(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

As a result, the reason why
it is still sending a text message first and then making a phone call cannot be interpreted as the reason why A executes first, so it sends a text message first, and still needs to focus on the lock

3. After adding a common method, send a text message or hello first;

public class Test2{
    
    
    public static void main(String[] args) {
    
    
        //两个对象,两个调用者,两把锁
        Phone2 phone = new Phone2();
        new Thread(()->{
    
    phone.sendSms();},"A").start();
        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        new Thread(()->{
    
    phone.hello();},"B").start();
    }
}
class Phone2{
    
    
    //synchronized锁的对象是方法的调用者
    //都是phone,因为用的同一把锁,所以谁先拿到谁先执行
    public synchronized void sendSms(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    public synchronized void call(){
    
    
        System.out.println("打电话");
    }
    //没有锁,不是同步方法
    public void hello(){
    
    
        System.out.println("Hello");
    }

}

As a result,
hello is executed first
because
the object of the synchronized lock is the caller of the method, because the hello() method is not locked, and there is no need to wait for the lock.

4. Two objects, two synchronization methods, send text messages or make phone calls

public class Test2{
    
    
    public static void main(String[] args) {
    
    
        //两个对象,两个调用者,两把锁
        Phone2 phone1 = new Phone2();
        Phone2 phone2 = new Phone2();
        new Thread(()->{
    
    phone1.sendSms();},"A").start();

        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        new Thread(()->{
    
    phone2.call();},"B").start();
    }
}
class Phone2{
    
    
    public synchronized void sendSms(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    public synchronized void call(){
    
    
        System.out.println("打电话");
    }
    //没有锁,不是同步方法
    public void hello(){
    
    
        System.out.println("Hello");
    }

}

result
The reason is that
the object of the synchronized lock is the caller of the method. At this time, we have two objects, phone1 and phone2, which do not affect each other, and because the method of sending text messages is delayed by 4 seconds, the call is executed first (this is a bit like solving a math problem in high school).

5. Add two static synchronization methods

class Phone3{
    
    
    public static synchronized void sendSms(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    public static synchronized void call(){
    
    
        System.out.println("打电话");
    }
   
}

Result
Send text message first, then call
reason
premise: The object of the synchronized lock is the caller of the method, because the same lock is used, so whoever gets it first executes it first
derive: static is static, it will be available as soon as the class is loaded, and the lock is Class, so it is still A that gets it first and executes it first to send a text message

6. For two objects, add two static synchronization methods

public class Test3{
    
    
    public static void main(String[] args) {
    
    
        //两个对象,两个调用者,两把锁
        Phone3 phone1 = new Phone3();
        Phone3 phone2 = new Phone3();

        new Thread(()->{
    
    phone1.sendSms();},"A").start();

        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        new Thread(()->{
    
    phone2.call();},"B").start();
    }
}
class Phone3{
    
    
    public static synchronized void sendSms(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    public static synchronized void call(){
    
    
        System.out.println("打电话");
    }

}


insert image description here
The reason for the result
Although there are two objects here, but because they are both static static methods, their real objects are the same, in fact, they are all the same class object—"Phone3's class is globally unique

7. A static synchronization method, a common synchronization method, who prints first

class Phone4{
    
    
    public static synchronized void sendSms(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    //普通同步方法
    public synchronized void call(){
    
    
        System.out.println("打电话");
    }
   
}

Result The reason for
calling first and then sending text messages is a static synchronization method and a common synchronization method, the objects of the two locks are different, and there is a 4-second delay in sending text messages.

8. A static synchronization method, a normal synchronization method, and two objects

public class Test4{
    
    
    public static void main(String[] args) {
    
    
        //两个对象,两个调用者,两把锁
        Phone4 phone = new Phone4();
        new Thread(()->{
    
    phone.sendSms();},"A").start();

        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        new Thread(()->{
    
    phone.call();},"B").start();
    }
}
class Phone4{
    
    
    public static synchronized void sendSms(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    //普通同步方法
    public  synchronized void call(){
    
    
        System.out.println("打电话");
    }
    //没有锁,不是同步方法
    public void hello(){
    
    
        System.out.println("Hello");
    }

}


insert image description here
The reason for the result
is not mentioned here, and everyone should understand it.

Guess you like

Origin blog.csdn.net/sand_wich/article/details/107747429