• Java八锁现象



    八锁现象

    一、简介

    • synchronized 锁的对象是方法的调用者
    • 两个方法用的是同一个锁,谁先拿到谁执行
    • 普通的方法是用对象操作的(同步方法 对象)
    • static静态方法是用Class操作的(静态同步方法 Class)
    • new this 具体的一个手机
    • static Class 唯一的一个模板

    八种情况:
    两个同步方法,一个对象(发短信,打电话)
    两个同步方法,一个对象,发短信延迟(发短信,打电话)
    一个同步方法,一个普通方法,一个对象,同步方法延迟(打电话,发短信)
    两个同步方法,两个对象,发短信延迟(打电话,发短信)
    两个静态同步方法,一个对象,发短信延迟(发短信,打电话)
    两个静态同步方法,两个对象,发短信延迟(发短信,打电话)
    一个静态同步方法,一个普通同步方法,一个对象,静态同步方法延迟(打电话,发短信)
    一个普通同步方法,一个静态同步方法,两个对象,静态同步方法延迟(打电话,发短信)

    二、代码案例

    1、案例1

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个同步方法,一个对象(发短信,打电话)
     */
    public class Lock01 {
        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 锁的对象是方法的调用者
        // 两个方法用的是同一个锁,谁先拿到谁执行
        public synchronized void sendSms() {
            System.out.println("发短信");
        }
    
        public synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    2、案例2

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个同步方法,一个对象,发短信延迟(发短信,打电话)
     */
    public class Lock02 {
        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.call();
            }, "B").start();
        }
    }
    
    class Phone2 {
    
        // synchronized 锁的对象是方法的调用者
        // 两个方法用的是同一个锁,谁先拿到谁执行
        public synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    3、案例3

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:一个同步方法,一个普通方法,一个对象,同步方法延迟(hello,发短信)
     */
    public class Lock03 {
        public static void main(String[] args) {
    
            Phone3 phone = new Phone3();
    
            new Thread(() -> {
                phone.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.call();
            }, "B").start();
        }
    }
    
    class Phone3 {
    
        public synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        // 没有锁,不是同步方法,不受锁的影响
        public  void call() {
            System.out.println("打电话");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    4、案例4

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个同步方法,两个对象,发短信延迟(打电话,发短信)
     */
    public class Lock04 {
        public static void main(String[] args) {
    
            // 两个对象,两个调用者,两把锁,与时间无关
            Phone4 phone1 = new Phone4();
            Phone4 phone2 = new Phone4();
    
            new Thread(() -> {
                phone1.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone2.call();
            }, "B").start();
        }
    }
    
    class Phone4 {
    
        // synchronized 锁的对象是方法的调用者
        // 两个方法用的是同一个锁,谁先拿到谁执行
        public synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public synchronized void call() {
            System.out.println("打电话");
        }
    }	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    5、案例5

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个静态同步方法,一个对象,发短信延迟(发短信,打电话)
     */
    public class Lock05 {
        public static void main(String[] args) {
    
            Phone5 phone = new Phone5();
    
            new Thread(() -> {
                phone.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.call();
            }, "B").start();
        }
    }
    
    class Phone5 {
    
        // static 静态方法
        // 类一加载就有了,锁的是Class
        public static synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public static synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    6、案例6

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个静态同步方法,两个对象,发短信延迟(发短信,打电话)
     */
    public class Lock06 {
        public static void main(String[] args) {
    
            // 两个对象的Class类模板只有一个,static,锁的是Class类Phone6
            Phone6 phone1 = new Phone6();
            Phone6 phone2 = new Phone6();
    
            new Thread(() -> {
                phone1.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone2.call();
            }, "B").start();
        }
    }
    
    // Phone6 唯一的一个 Class 对象
    class Phone6 {
    
        // static 静态方法
        // 类一加载就有了,锁的是Class
        public static synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public static synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    7、案例7

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:一个静态同步方法,一个普通同步方法,一个对象,静态同步方法延迟(打电话,发短信)
     */
    public class Lock07 {
        public static void main(String[] args) {
    
            Phone7 phone = new Phone7();
    
            new Thread(() -> {
                phone.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.call();
            }, "B").start();
        }
    }
    
    class Phone7 {
    
        //  静态同步方法,锁的是Class类模板
        public static synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        // 普通同步方法,锁的是调用者
        public synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    8、案例8

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:一个普通同步方法,一个静态同步方法,两个对象,静态同步方法延迟(打电话,发短信)
     */
    public class Lock08 {
        public static void main(String[] args) {
    
            // 两个对象的Class类模板只有一个,static,锁的是Class类Phone6
            Phone8 phone1 = new Phone8();
            Phone8 phone2 = new Phone8();
    
            new Thread(() -> {
                phone1.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone2.call();
            }, "B").start();
        }
    }
    
    class Phone8 {
    
        // static 静态方法
        // 类一加载就有了,锁的是Class
        public static synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
  • 相关阅读:
    Spring(三)- Spring中Bean的配置
    Java面试笔试acm版输入
    金融用户实践|分布式存储支持数据仓库业务系统性能验证
    第4章_3——索引的使用
    【Kotlin】private、 protected、 internal 和 public指定修饰符的区别
    【C#】【FFmpeg】获取电脑可用音视频设备并输出到下拉列表框
    OpenGL简介
    Vulnhub靶场之Funbox
    Tessent IJTAGug系列 -第一章 IJTAG介绍
    要想不踩SaaS那些坑,得先了解“SaaS架构”
  • 原文地址:https://blog.csdn.net/s17856147699/article/details/126598600