zoukankan      html  css  js  c++  java
  • 八锁现象

    1、标准访问,请问先打印邮件还是短信?

    package com.dakuzai.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * **1、标准访问,请问先打印邮件1还是短信2?**
     * 
     * 
     */
    public class Test1 {
        public static void main(String[] args) {
            
            Phone phone = new Phone();
    
            // 我们这里两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(() -> {
                phone.sendEmail();
            }, "A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.sendMS();
            }, "B").start();
    
        }
    }
    
    // 手机,发短信,发邮件
    class Phone {
        // 被 synchronized 修饰的方法、锁的对象是方法的调用者、
        public synchronized void sendEmail() {
            System.out.println("sendEmail");
        }
    
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    }
    

    2、邮件方法暂停4秒钟,请问先打印邮件还是短信?

    package com.dakuzai.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * **2、邮件方法暂停4秒钟,请问先打印邮件还是短信?**
     */
    public class Test2 {
        public static void main(String[] args) {
    
            Phone2 phone = new Phone2();
    
            // 我们这里两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(() -> {
                phone.sendEmail();
            }, "A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.sendMS();
            }, "B").start();
    
        }
    }
    
    
    // 手机,发短信,发邮件
    class Phone2 {
        // 被 synchronized 修饰的方法、锁的对象是方法的调用者、
        public synchronized void sendEmail() {
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    }
    

    3、新增一个普通方法hello()没有同步,请问先打印邮件还是hello?

    package com.dakuzai.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 3、新增一个普通方法hello()没有同步,请问先打印邮件还是hello?
     */
    public class Test3 {
    
        // 回家  卧室(锁)   厕所
        public static void main(String[] args) {
    
            Phone3 phone = new Phone3();
    
            // 我们这里两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(() -> { // 一开始就执行了
                phone.sendEmail();
            }, "A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> { // 一秒后执行
                phone.hello();
            }, "B").start();
    
        }
    }
    
    // 锁:竞争机制
    
    // 手机,发短信,发邮件
    class Phone3 {
        // 被 synchronized 修饰的方法、锁的对象是方法的调用者、
        public synchronized void sendEmail() {
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    
        // 新增的方法没有被 synchronized 修饰,不是同步方法,所以不需要等待,其他线程用了一个把锁
        public void hello() {
            System.out.println("hello");
        }
    
    }
    

    4、两部手机、请问先打印邮件还是短信?

    package com.dakuzai.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * **4、两部手机、请问先打印邮件还是短信?**
     */
    public class Test4 {
    
        // 回家  卧室(锁)   厕所
        public static void main(String[] args) {
            // 两个对象,互不干预
            Phone4 phone1 = new Phone4();
            Phone4 phone2 = new Phone4();
    
            // 我们这里两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(() -> { // 一开始就执行了
                phone1.sendEmail();
            }, "A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> { // 一秒后执行
                phone2.sendMS();
            }, "B").start();
    
        }
    
    }
    
    // 手机,发短信,发邮件
    class Phone4 {
        // 被 synchronized 修饰的方法、锁的对象是方法的调用者、调用者不同,没有关系,两个方法用得不是同一个锁!
        public synchronized void sendEmail() {
            // 善意的延迟
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    
    }
    

    5、两个静态同步方法,同一部手机,请问先打印邮件还是短信?

    package com.dakuzai.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /*
     **5、两个静态同步方法,同一部手机,请问先打印邮件还是短信?**
     */
    public class Test5 {
        // 回家  卧室(锁)   厕所
        public static void main(String[] args) {
            // 两个对象,互不干预
            Phone5 phone = new Phone5();
    
            // 我们这里两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(() -> { // 一开始就执行了
                phone.sendEmail();
            }, "A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> { // 一秒后执行
                phone.sendMS();
            }, "B").start();
    
        }
    
    }
    
    
    // 手机,发短信,发邮件
    class Phone5 {
    
        // 对象    类模板可以new 多个对象!
        // Class   类模版,只有一个
    
        // 被 synchronized 修饰 和 static 修饰的方法,锁的对象是类的 class 对象!唯一的
        // 同一把锁
    
        public static synchronized void sendEmail() {
            // 善意的延迟
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        public static synchronized void sendMS() {
            System.out.println("sendMS");
        }
    
    }
    

    6、两个静态同步方法,2部手机,请问先打印邮件还是短信?

    package com.dakuzai.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /** 第一次听可能不会,第二次也可能不会,但是不要放弃,你可以!
     **6、两个静态同步方法,2部手机,请问先打印邮件还是短信?**
     */
    public class Test6 {
    
        // 回家  卧室(锁)   厕所
        public static void main(String[] args) {
            // 两个对象,互不干预
            Phone5 phone = new Phone5();
            Phone5 phone2 = new Phone5();
    
            // 我们这里两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(() -> { // 一开始就执行了
                phone.sendEmail();
            }, "A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> { // 一秒后执行
                phone2.sendMS();
            }, "B").start();
    
        }
    
    }
    
    // 手机,发短信,发邮件
    class Phone6 {
    
        // 对象    类模板可以new 多个对象!
        // Class   类模版,只有一个
    
        // 被 synchronized 修饰 和 static 修饰的方法,锁的对象是类的 class 对象!唯一的
        // 同一把锁
    
        public static synchronized void sendEmail() {
            // 善意的延迟
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        public static synchronized void sendMS() {
            System.out.println("sendMS");
        }
    
    }
    

    7、一个普通同步方法,一个静态同步方法,同一部手机,请问先打印邮件还是短信?

    package com.dakuzai.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 7、一个普通同步方法,一个静态同步方法,同一部手机,请问先打印邮件还是短信?**
     */
    public class Test7 {
        // 回家  卧室(锁)   厕所
        public static void main(String[] args) {
            // 两个对象,互不干预
            Phone7 phone = new Phone7();
    
            // 我们这里两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(() -> { // 一开始就执行了
                phone.sendEmail();
            }, "A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> { // 一秒后执行
                phone.sendMS();
            }, "B").start();
    
        }
    }
    
    
    class Phone7{
        // CLASS
        public static synchronized void sendEmail() {
            // 善意的延迟
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        // 对象
        // 普通同步方法
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    
    }
    

    8、一个普通同步方法,一个静态同步方法,2部手机,请问先打印邮件还是短信?

    package com.dakuzai.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * **8、一个普通同步方法,一个静态同步方法,2部手机,请问先打印邮件还是短信?**
     */
    public class Test8 {
    
        public static void main(String[] args) {
            // 两个对象,互不干预
            Phone8 phone = new Phone8();
            Phone8 phone2 = new Phone8();
    
            // 我们这里两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(() -> { // 一开始就执行了
                phone.sendEmail();
            }, "A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> { // 一秒后执行
                phone2.sendMS();
            }, "B").start();
    
        }
    
    }
    
    
    
    class Phone8{
    
        // CLASS
        public static synchronized void sendEmail() {
            // 善意的延迟
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        // 对象
        // 普通同步方法
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    
    }
    

    小结

    new this 本身的这个对象,调用者

    static class 类模板,保证唯一!

    • 一个对象中有多个 synchronized 方法,某个时刻内只要有一个线程去访问 synchronized 方法了就会被加锁,其他线程就会阻塞!

    • 加了一个普通方法后 ,两个对象,无关先后,一个有锁,一个没锁!情况会变化!

    • 换成静态同步方法,情况会变化! CLASS ,所有静态同步方法的锁唯一 对象实例class 本身!

  • 相关阅读:
    联想 Vibe Shot(Z90-3) 免recovery 获取ROOT权限 救砖 VIBEUI V3.1_1625
    联想 Z5S(L78071)免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.370
    联想 Z5(L78011) 免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.254
    联想 S5 Pro(L78041)免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 5.0.123
    第二阶段 冲刺八
    第二阶段 冲刺七
    第二阶段 冲刺六
    第二阶段 冲刺五
    代码大全阅读笔记03
    学习进度十二
  • 原文地址:https://www.cnblogs.com/dakuzai/p/13438588.html
Copyright © 2011-2022 走看看